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
72 changes: 72 additions & 0 deletions .github/ISSUE_TEMPLATE/release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
name: Release
about: One monthly release of arcadedb-jvm and arcadedb (native), step by step
title: "Release <VERSION>"
labels: ""
---

Open this issue once per release, when upstream ArcadeDB has released an engine version. Replace the placeholders everywhere on this page before you start:

- `<VERSION>`: the tag to push, for example the engine release `A.B.C`. A Python-only fix of a released engine is `A.B.C.postN`.
- `<PREVIOUS>`: the previous release of the same package on PyPI (the JVM and the native package can differ), or `-` for the first release of a package.
- `<NEXT_DEV>`: the first dev version of the next base, `A.B.C.dev0` (see step 7).

Every step says who does it: script (run the command, read the result), CI (a workflow does it, you wait), or owner (a decision that is not automated). The procedure and the reasons are on the docs page `development/release.adoc`, section "Release day".

## Before the tag

- [ ] 1. script: upstream `<VERSION>` is out on both channels (GitHub release, Maven Central, Docker Hub image), the version rule holds for both packages, the CI of `main` is green, and the release workflows derive the right version and engine. Zero FAILs means ready. A FAIL on Maven Central or Docker Hub can mean the other channel is still catching up: run it again later.

```bash
uv run --no-project python -I scripts/release_preflight.py <VERSION>
```

- [ ] 2. owner: for a final or post release, the native readiness bar is met and the repository variable `ARCADEDB_NATIVE_READINESS_BAR_MET` is `true` (the preflight line `(g)` shows it, or SKIPs when the login cannot read variables).
- [ ] 3. owner: the go. Nothing is published before this box is ticked.

## The tag (the only publishing step)

- [ ] 4. owner: push the tag. It is the bare version, with no `v`, on the tip of `main`. One tag starts `release-jvm.yml` and `release-native.yml`.

```bash
git fetch origin main --no-tags && git tag <VERSION> origin/main && git push origin <VERSION>
```

- [ ] 5. CI: both release workflows finish and publish. Note the two run ids (the native build takes the longest). To retry a failed upload, re-run only the publish job, never the whole workflow.

```bash
gh run list -R ArcadeData/arcadedb-python --branch <VERSION> --limit 6
gh run watch <run-id> -R ArcadeData/arcadedb-python
```

## After the tag

- [ ] 6. script: verify both packages on PyPI. Run them under bash. The scripts read from GitHub and PyPI only, and download about 0.6 GB: point `WORK` at a disk, not a tmpfs. The exit code is the number of FAILs.

```bash
scripts/after_tag_verify.sh <VERSION> <PREVIOUS> <jvm-run-id>
PACKAGE=native scripts/after_tag_verify.sh <VERSION> <PREVIOUS> <native-run-id>
```

- [ ] 7. script, then CI: the dev-engine bump PR. Open it from a worktree on a branch off `origin/main`. Pick `<NEXT_DEV>` from the version of upstream `main`: the command prints the next base. If it prints `<VERSION>`, upstream has not moved on yet: wait, because a dev version of a released base is refused.

```bash
curl -fsS https://raw.githubusercontent.com/ArcadeData/arcadedb/main/pom.xml | sed -n '/<artifactId>arcadedb-parent<\/artifactId>/,/<\/version>/ s/.*<version>\(.*\)-SNAPSHOT<\/version>.*/\1/p'
# <NEXT_DEV> is that base followed by .dev0
uv run --no-project python scripts/bump_engine.py --engine <VERSION> --dev-version <NEXT_DEV> --check
uv run --no-project python scripts/bump_engine.py --engine <VERSION> --dev-version <NEXT_DEV>
```

- [ ] 8. script: refresh the notices the new engine needs. The first `Test native` run on the bump PR stops at the notices drift check on purpose and uploads the generated file. Download it, commit it, push, and wait for the run to go green.

```bash
gh run list -R ArcadeData/arcadedb-python --workflow test-native.yml --branch <bump-branch> --limit 1
gh run download <run-id> -R ArcadeData/arcadedb-python -n native-build-record-linux-x86_64 -D <scratch-dir>
cp <scratch-dir>/THIRD_PARTY_NOTICES.generated.md native/wheel/THIRD_PARTY_NOTICES.md
uv run --no-project python scripts/bump_engine.py --engine <VERSION> --dev-version <NEXT_DEV> --check
```

If the engine NOTICE changed, also refresh the kept copy with `git -C <arcadedb clone> show <VERSION>:NOTICE > native/wheel/ARCADEDB_ENGINE_NOTICE`.

- [ ] 9. CI, then owner: merge the bump PR when every check is green, and delete the branch and the worktree. Then remove the tests and skip-list lines that waited for the new engine: `git grep -n -i "native build links\|native image links"`.
- [ ] 10. owner: close this issue with the two run ids and the two PyPI links.
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,6 @@ Each package has one test and one release workflow: `test-jvm.yml` and `release-

`.github/workflows/test-jvm.yml` builds ONE wheel per platform (linux/amd64, linux/arm64, darwin/arm64, windows/amd64), tagged `py3-none-<platform>` by `setup.py` (`bdist_wheel.get_tag`; `scripts/verify_wheel_tag.py` checks it), and tests that wheel on Python 3.11–3.14; also runs nightly against `arcadedata/arcadedb:latest`. `requires-python` is `>=3.11,<3.15` because the tag no longer keeps pip off 3.15 and JPype has no 3.15 wheel; drop the cap with it. The org shares a runner cap with upstream, so the unit tests run 10 legs on every event (linux/amd64 on all four Pythons, the other three platforms on 3.11 and 3.14, the shape of test-native.yml), and the examples run all four platforms on 3.14 on a pull request (4 legs, 28 checks in all) and 16 legs on push to main, the nightly run, dispatch and the release (40 checks). `scripts/select_matrix.py` holds both lists (`PULL_REQUEST_LEGS`, keyed `jvm` and `examples`), the first job of each workflow runs it, and `tests/test_select_matrix.py` pins the full matrix; docs page `development/ci.adoc`. Keep the job names `Test arcadedb (<platform>, Python <version>)` unchanged. Both workflows accept an `arcadedb-tag` input to pin the image. `test-python-examples.yml` runs `examples/`. A dependency-floor audit locks the dependencies and extras on a throwaway uv project with `--resolution lowest-direct` for each Python classifier and runs `uvx pip-audit` on the export, so raise lower bounds when a floor has an advisory. No tool is installed with pip anywhere in CI or the scripts: one-off tools run through `uvx tool==X`, the wheel is built with `uvx --from "build[uv]==1.6.1" pyproject-build --installer uv`, and the uv install URL is pinned (`0.12.0`).

`.github/workflows/release-jvm.yml` publishes `arcadedb-jvm` on a bare-version tag (`26.11.1.dev0`, `26.11.1`, `26.11.1.post1`; no `v`, never `aN`/`bN`/`rcN`). Its first job runs `scripts/check_version.py` (the devN/postN counting rule, read-only, fails closed); `scripts/after_tag_verify.sh` checks the finished release. The rule is stated once, on the docs page `development/release.adoc`.
`.github/workflows/release-jvm.yml` publishes `arcadedb-jvm` on a bare-version tag (`26.11.1.dev0`, `26.11.1`, `26.11.1.post1`; no `v`, never `aN`/`bN`/`rcN`). Its first job runs `scripts/check_version.py` (the devN/postN counting rule, read-only, fails closed); `scripts/release_preflight.py <VERSION>` checks everything before the tag (read-only); `scripts/after_tag_verify.sh` (`PACKAGE=native` for `arcadedb`) checks the finished release; `scripts/bump_engine.py` moves the dev-engine pins after a release. The monthly steps are the "Release day" section of `development/release.adoc` and the issue template `.github/ISSUE_TEMPLATE/release.md`. The rule is stated once, on the docs page `development/release.adoc`.

`test-native.yml` builds the GraalVM native image and runs the parity suite against the installed wheel (selective: scripts/select_native_matrix.py, 5 to 30 minutes per platform, do not add runs lightly). `.github/workflows/release-native.yml` publishes `arcadedb` on the same tag: it calls `test-native.yml` with `release: true` (4 platforms x Python 3.11 to 3.14), then the readiness gate (the repository variable `ARCADEDB_NATIVE_READINESS_BAR_MET`, for a final or post version), then one publish job through the environment `pypi`.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ Releases from this repository start with 26.11.1. The 26.10.x wheels were built

The `arcadedb` (native) wheel is built from `native/` with GraalVM Community Edition; [`CLAUDE.md`](https://github.com/ArcadeData/arcadedb-python/blob/main/CLAUDE.md) has the commands. A native image build takes about 5 to 30 minutes per platform (macOS is the slowest).

The JVM build runs in Docker on Linux. macOS and Windows need a JDK 25 or later. The jars come from the `arcadedata/arcadedb` Docker image: `latest` by default, or the tag in `ARCADEDB_TAG` (for example `ARCADEDB_TAG=26.10.2 ./scripts/build.sh`). The package version is read from the engine jar in that image, so a `26.11.1-SNAPSHOT` image builds `26.11.1.devN`.
The JVM build runs in Docker on Linux. macOS and Windows need a JDK 25 or later. The jars come from the `arcadedata/arcadedb` Docker image: `latest` by default, or the tag in `ARCADEDB_TAG` (for example `ARCADEDB_TAG=26.10.2 ./scripts/build.sh`). The package version is read from the engine jar in that image, so an `A.B.C-SNAPSHOT` image builds `A.B.C.devN`.

The native build does not use the image. It resolves `arcadedb-engine` and `arcadedb-server` from Maven Central at `arcadedb.version` in `native/pom.xml` (release versions only, because a snapshot is not on Maven Central) and compiles them with GraalVM Community Edition. Neither build compiles the engine from source: the engine code is upstream's, unmodified.

Tests run against the built wheel, not the source tree: install the wheel with its `test` extra into a virtual environment, then run `pytest`. [`CLAUDE.md`](https://github.com/ArcadeData/arcadedb-python/blob/main/CLAUDE.md) has the exact commands, the build options and the lint setup.

Expand Down
9 changes: 9 additions & 0 deletions docs/modules/ROOT/pages/development/ci.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ The names of the test jobs do not change: `Test arcadedb (<platform>, Python <ve

`release-jvm.yml` expects exactly four wheels, one for each platform, all `py3-none`. It checks the count, the tags, the sizes and the names before it publishes. The nightly run also tests against the newest `arcadedata/arcadedb:latest` image.

== Which engine each workflow tests

The two packages get their engine from different places, so between releases they are tested against different engines:

* `test-jvm.yml` and `test-python-examples.yml` take the engine jars from the `arcadedata/arcadedb` image tag, `latest` by default. `latest` is upstream's newest snapshot and moves nightly, which is why both workflows also run every night.
* `test-native.yml` links `DEV_ENGINE`, the newest release on Maven Central, unless the tag is a final or post version (then it links the release the tag is named after) or the `engine` input of a manual run says otherwise.

The dev-engine bump after each release, described in xref:development/release.adoc[Release], moves `DEV_ENGINE` to the new release and closes the gap until upstream publishes the next one.

== Other rules

* A pull request that changes only documentation (`docs/**`, `*.adoc`, `CLAUDE.md`, `examples/README.md`, `LICENSE*`) runs nothing.
Expand Down
Loading
Loading