Skip to content

Add release workflow publishing to PyPI by trusted publishing - #22

Open
tae898 wants to merge 1 commit into
mainfrom
ci/release-workflow
Open

tae898 wants to merge 1 commit into
mainfrom
ci/release-workflow

Conversation

@tae898

@tae898 tae898 commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator

Adds .github/workflows/release.yml, ported from release-python-packages.yml in humemai/arcadedb-embedded-python, for the release-workflow box of #19 and the PyPI discussion in #18. Draft: CI and release changes wait for review. Nothing here has been run on GitHub, no tag was pushed and no workflow was dispatched.

What it does

A push of a bare-version tag (26.11.1, 26.11.1.post1, 26.11.1.dev0; no v, same as ArcadeData/arcadedb) runs these jobs:

  1. validate-version: the tag must match A.B.C, A.B.C.devN or A.B.C.postN (so aN, bN, rcN and v-prefixed tags are rejected). It derives the arcadedata/arcadedb image tag: the base version for release and post tags, latest for dev tags.
  2. test and test-examples: call the existing test-python-bindings.yml and test-python-examples.yml through workflow_call with arcadedb-tag and build-version (both inputs already exist). They download the jars, build a wheel for each of 4 platforms and each Python version in the matrix (3.10 to 3.14, 20 wheels), run the tests and upload wheel-<platform>-py<version>. A pinned arcadedb-tag already fails there when the image holds another engine version.
  3. verify-wheels (no publish rights): the tag must equal the version derived from the engine jar (extract_version.py --format=docker, -SNAPSHOT allowed only with a .devN tag and required for it); wheel count is 4 platforms x the Python versions in the pyproject.toml classifiers, with the per-platform count checked too; every wheel's version equals the tag; every wheel is under 100 MB through scripts/verify_wheel_size.py (no override); all wheels agree on distribution name and one import package. Uploads the checked wheels as release-dist.
  4. publish: environment: pypi, permissions: id-token: write on this job only (the workflow default is contents: read), pypa/gh-action-pypi-publish. No token or secret anywhere.
  5. verify-pypi: after the upload, installs arcadedb==<tag> from PyPI with uv run --no-project --with on linux/amd64, linux/arm64, macOS arm64 and Windows amd64 (the same runners the test matrix uses, all standard), checks the installed version and imports the package (retries for up to 5 minutes while PyPI catches up).

All actions are pinned by SHA to the ones the repo's workflows and ArcadeData/arcadedb-drivers' publish-python.yml already use. uv is only used as uv run. No paid runners.

Differences from the humemai workflow: the tag-versus-jar check moves from a pom.xml comparison to the engine jar (this repo has no pom.xml), the 16-wheel count follows the classifiers instead of a literal, continue-on-error on the publish job is gone (a failed upload should fail the release), and the PyPI install check is new.

The guard

The publish job starts by refusing unless every wheel is the distribution arcadedb: both the wheel file name and the Name field of its METADATA must normalise to arcadedb. pyproject.toml still names the distribution arcadedb-embedded, so today a tag push builds and tests everything, then stops in this step before anything reaches PyPI. The rename is a separate PR (box in #19) and I did not touch pyproject.toml. I ran the guard script locally against fake arcadedb_embedded and arcadedb wheels: it fails the first and passes the second.

What it relies on (already set up)

  • PyPI trusted publisher: project arcadedb from ArcadeData/arcadedb-python, workflow release.yml, environment pypi. Project arcadedb-native has the same repository and workflow with environment pypi-native; this PR has no native job yet, only a commented TODO at the top of the file.
  • GitHub environments pypi and pypi-native exist in this repository, each limited by a deployment rule to tags matching [0-9]*.
  • PyPI ownership: the humemai account owns arcadedb, arcadedb-embedded, arcadedb-native and arcadedb-embedded-native; @robfrank co-owns arcadedb and arcadedb-native.
  • Versions run A.B.C.devN, then A.B.C, then A.B.C.postN (devN starts at 0, postN at 1). From the first release here (26.11.1) the JVM wheels publish as arcadedb; arcadedb-embedded keeps releasing from the humemai repo until then.

Dependencies on #19

  • Distribution rename arcadedb-embedded to arcadedb in pyproject.toml (and the import package, which the PyPI check reads from the wheel instead of hard-coding). Blocks any real publish, by design of the guard.
  • The remaining ports that change what the wheels contain (JRE trim, Studio jar out, runtime fixes) do not block the workflow itself; they decide what 26.11.1 ships. The wheel size policy and the 30 MB lower warning in verify_wheel_size.py already exist here.
  • Native wheel (native-wheel/, native-preview.yml, native-alias.yml): not ported, so there is no arcadedb-native job. It comes with that port, in environment pypi-native.
  • The nightly schedule of the two test workflows does not apply to tags; nothing needed here.

What ran locally

  • actionlint 1.7.12 (the version the repo's pre-commit pins) with shellcheck 0.11.0 over every run: block: clean. The repo's .github/actionlint.yaml ignores were not needed for the new file.
  • The tag regex against 26.11.1, .dev0, .post1 (accepted) and rc1, a1, v26.11.1, bare .dev (rejected).
  • The guard script against fake wheels, and a syntax parse of the two inline Python blocks.
  • pytest on test_build_scripts, test_wheel_size, test_wheel_platform_tag, test_extract_version*, test_build_wheel_check and test_no_monorepo_wording: 59 passed; 1 failed (test_dunder_version_matches_distribution_metadata) only because the package is not installed in that bare environment.

Not verified: a real run of the jobs on GitHub (needs a tag, so it waits for review), and the verify-pypi retry loop.

🤖 Generated with Claude Code

Tag push (bare version) -> validate tag -> build and test wheels via the
existing test workflows -> verify jar version, wheel count, versions and size
-> publish job (environment pypi, id-token only there) with a guard that
refuses anything but the distribution `arcadedb` -> install from PyPI and
import on four platforms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tae898
tae898 marked this pull request as ready for review October 23, 2026 12:32
@tae898
tae898 requested a review from robfrank October 23, 2026 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant