clients/py, clients/py_server, run_pypi.sh
gligabao is published on PyPI as two packages, so that people who only call gligabao do not download the server:
./run_pypi.sh.
How the server package works
pip cannot compile Go, so the wheels contain a binary that was cross-compiled beforehand (the same approach as ruff or uv). For each targetrun_pypi.sh:
- builds
./cmd/gligabaowithCGO_ENABLED=0 GOOS=<os> GOARCH=<arch>(the build is pure Go and static, so cross-compiling needs nothing but the Go toolchain); - assembles a staging directory
build/pypi/server-<os>-<arch>/with the package sources, the binary and a copy ofbuild/gligabao.toml, and writes the version of theVERSIONfile into_version.pythere (the server package has the version of the server; the client has its own, inclients/py/pyproject.toml); - builds a wheel from it with hatchling.
hatch_build.pymarks the wheel as platform specific and sets its tag fromGLIGABAO_WHEEL_TAG.
pip install gligabao-server then picks the wheel matching the machine. An sdist is not published (it would have no binary). Nothing is generated inside clients/py_server itself; its _bin/ directory only exists in the staging directories.
What is installed
gligabao_server/_bin/gligabao(gligabao.exeon Windows), executable.gligabao_server/_bin/gligabao.toml, the repo’sbuild/gligabao.toml. The binary reads its config from next to itself unless--configis given, so the packaged file is the default. It lives in site-packages and is replaced when the package is upgraded: keep your own settings in a file elsewhere and rungligabao-server serve --config <path>.- The commands
gligabao-serverandgligabao, which run the binary with the same arguments;gligabao_server.binary_path()andgligabao_server.config_path()for Python code. - Not included: the Python sidecar (
sidecar/, training). Use the Docker image for it. The directories the config names (datasets_training,evals_*,ontology) are not shipped either; they are resolved like for any other binary, relative to the database or as given by the flags. - The database and its neighbours (
--db, defaultdata/gligabao.db) are created relative to the current directory, not in site-packages.
Building
Building and uploading are separate steps: building writes into thedist/ directory of each package, uploading sends what is in those directories. Giving both in one call does both, building first.
- The admin UI is built once per call (
admin_ui/, needs node and npm, like./run_build.sh) and embedded in every binary.--no-admin-uileaves it out. - Tests run first: the client tests before the client is built, the launcher tests before the server wheels.
- A build replaces only the file of its own target and version. Building Linux today and macOS tomorrow leaves both in
dist/, anddist/may keep wheels of older versions (they are never uploaded). - Each wheel is checked with
twine check.
Uploading
--upload sends every file of the current versions that is in the dist/ directories: the client’s wheel and sdist (version from clients/py/pyproject.toml) and all server wheels that were built (version from VERSION). It lists them and asks for confirmation (--yes skips it). If a platform was never built, it is not uploaded, so build all platforms before the release. PyPI never accepts the same file twice: to republish, bump the version.
Release steps for a new server version: bump VERSION and the changelog (see AGENTS.md of the gligabao repository); build everything; upload to TestPyPI and try pip install -i https://test.pypi.org/simple/ gligabao-server; upload to PyPI. A new client version only needs version in clients/py/pyproject.toml raised.
Notes
- Wheel size is about 20 MB per platform without the admin UI, a bit more with it (PyPI’s limit is 100 MB per file).
- The minimum macOS version of the wheels follows the Go toolchain’s; raise
macosx_12_0_*inrun_pypi.shwhen Go does. - Building Windows or macOS wheels on Linux works, but only the host’s platform is run by the script; try the others on a real machine before a release.