Commit 9fb69b6
refactor: split packages and add release machinery (#5)
* refactor: split workspace, publish server image to GHCR
Rework the OSS release machinery to mirror FlowMesh's pattern: the
``lumilake`` distribution becomes a thin metapackage with extras
``[sdk]``/``[cli]``/``[deploy]``/``[hook]``/``[all]`` that pull in
four workspace wheels; the server runtime lives in ``src/lumilake_server/``
and ships only inside the Docker image, never on PyPI.
Workspace:
- packages/sdk publishes the ``lumilake`` Python module (Client, envs,
log). Other workspace packages depend on it as the shared base.
- packages/cli publishes ``lumilake_cli`` (Typer entry point ``lumilake``).
- packages/deploy publishes ``lumilake_deploy`` (Docker / FlowMesh glue).
- packages/hook publishes ``lumilake_hook`` (lumid-hooks bindings).
- Server code moved from ``src/lumilake/*`` to ``src/lumilake_server/*``;
it stays out of every wheel.
Image release:
- New ``.github/workflows/image-publish.yml`` builds linux/amd64+arm64
via buildx and pushes to ``ghcr.io/mlsys-io/lumilake_server`` with
tags ``:<sha>`` per push, ``:dev`` on main, and ``:<semver>`` + ``:latest``
on tag-v*. GHCR auth uses the workflow's ``GITHUB_TOKEN``.
- ``scripts/dev/sync_requirements.py`` derives
``src/lumilake_server/requirements.txt`` from the ``server-runtime``
uv dependency group so the Dockerfile's pin set tracks ``uv.lock``.
- Dockerfile rewritten to install the published ``lumilake-sdk`` wheel
plus the generated requirements, copy ``src/lumilake_server/`` onto
``PYTHONPATH``, and run ``python -m lumilake_server.main``.
- docker-compose ``server`` service now pulls
``\${LUMILAKE_REGISTRY:-ghcr.io/mlsys-io}/lumilake_server:\${LUMILAKE_IMAGE_TAG:-latest}``
(no ``build:`` stanza).
CLI:
- ``LUMILAKE_REGISTRY`` env var (default ``ghcr.io/mlsys-io``) selects
the image registry.
- New ``lumilake deploy pull`` command pulls the published image.
- ``lumilake deploy up`` no longer auto-builds — it fails fast if the
image is missing, pointing the user at ``pull`` or ``build``.
- ``lumilake deploy build`` retains source builds (re-tagged for GHCR).
PyPI publish:
- ``.github/workflows/package-build.yml`` now builds all workspace
packages (``uv build --all-packages``) and, on a tag-v*, uploads the
dist artifact and publishes via OIDC trusted publishing
(``pypa/gh-action-pypi-publish``).
- ``scripts/ci/check_package_build.py`` validates the metapackage is
code-free, each workspace wheel ships its top-level module, none of
them contain ``lumilake_server/``, and smoke-installs every extra.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Zhengyuan Su <su.zhengyuan@u.nus.edu>
* refactor: harden release machinery and packaged deploy assets
Post-review tightening of the GHCR + PyPI release flow introduced in
5d5ed47. Adopts FlowMesh's release-day machinery and moves the deploy
templates into ``lumilake-deploy`` package data so PyPI users can run
``lumilake deploy`` without a source checkout.
Release machinery (FlowMesh-aligned):
- ``docs/RELEASE.md`` runbook covers PyPI Trusted Publisher pending-
publisher setup, GHCR visibility + repo-link manual steps,
``pypi`` / ``testpypi`` / ``ghcr`` environment approvals, and the
rollback recipes (yank, ``.postN``, "PyPI succeeded but image
broken").
- ``scripts/ci/check_release_version.py`` cross-checks every
``version = ...`` string across the 5 pyprojects + 2 ``__version__``
literals against the release tag.
- ``scripts/dev/bump_version.py`` writes them in one pass; release.yml
re-runs ``--check`` after the version validator for belt-and-suspenders.
- ``scripts/ci/check_image_release.py`` verifies the published image's
per-platform OCI labels match the release tag + commit, polls for the
manifest (race-safe against image-publish.yml), and is the gate for
the ``:latest`` retag.
- ``scripts/ci/retag_image_release.py`` writes ``:latest`` via
``docker buildx imagetools create``, with downgrade and
missing-label-protection guards.
- ``scripts/ci/filter_distributions.py`` trims dist files for staggered
Trusted Publisher onboarding.
- ``scripts/ci/append_release_digests.py`` sentinel-replace edits the
Release body with the digest table, idempotent across re-runs.
- New ``.github/workflows/release.yml`` (PyPI publish; GitHub release
event, ``pypi`` environment approval) + ``release-images.yml``
(``:latest`` retag; ``ghcr`` environment approval). Both run on
``self-hosted`` to match FlowMesh.
- ``image-publish.yml`` keeps pushing ``:sha`` / ``:dev`` / ``:vX.Y.Z``
per commit/tag but no longer pushes ``:latest`` (release-images owns
it). Adds a post-push native-arch smoke (``import lumilake,
lumilake_hook, lumilake_server``).
- ``package-build.yml`` reduced to PR/main build + verify + ``twine
check``; PyPI publish moved entirely to ``release.yml``.
Packaged deploy assets:
- ``.env.example`` and ``docker-compose.yml`` moved into
``packages/deploy/src/lumilake_deploy/assets/`` (compose renamed
``compose.yml``); root ``.env.example`` is now a symlink for editor /
IDE convenience, matching FlowMesh.
- New ``lumilake_deploy.assets`` module exposes ``asset_path`` /
``env_example_path`` / ``compose_path`` via ``importlib.resources``
so the deploy CLI works from any directory after a ``pip install``.
- ``deploy init`` reads the packaged template; ``setup.py`` / ``stop.py``
run ``docker compose -f <compose_path()> --project-directory
<deploy_dir>``. ``build_server_image`` now raises a friendly error
when invoked without a source checkout's Dockerfile.
``-C`` / ``--project-dir`` (+ ``LUMILAKE_DEPLOY_DIR``) for the deploy
CLI: every subcommand of ``lumilake deploy`` reads the env / compose
project dir from the new option / env var, defaulting to cwd. Removes
the source-checkout-required walker.
CLI weight split: ``lumilake-cli`` drops ``lumilake-deploy`` from hard
deps, exposes it as ``[deploy]`` extra. ``lumilake[cli]`` keeps the
full lifecycle. ``commands/__init__.py`` uses ``find_spec`` to gate the
deploy subcommands (real ImportError inside .deploy bubbles up loudly).
Thin-install users hit an install hint for every deploy subcommand
instead of typer's bare "No such command".
SDK polish:
- ``packages/sdk/src/lumilake/py.typed`` marker added.
- ``resources/deploy.py`` switches the backend gate to ``find_spec``,
reads ``ENV_FILE_NAME`` from the packaged constants, and resolves
FlowMesh container names from ``.env.flowmesh`` via the shared
``lumilake_deploy.containers`` helper (was hardcoded
``flowmesh_node_*``). Exports ``SERVICE_NAMES`` (the slug-prefixed
container names are per-deploy and resolved at call time).
stop.py ``--wipe-archive`` derives the FlowMesh state-volume names from
the same slug helper so an operator who ran ``init --flowmesh`` with
the default ``lumilake`` suffix actually has their FlowMesh volumes
removed.
Per-package ``LICENSE`` files committed (workspace wheels were
previously shipping without LICENSE due to a parent-traversal
``license-files``). ``check_package_build.py`` SHA-verifies every
wheel's bundled LICENSE matches the repo root; it also catches
flat-file leaks and enforces ``lumilake_server`` absent from every
wheel.
Server runtime / Dockerfile: non-root ``lumilake`` user (uid 10001),
``tini`` PID-1 + exec-form ``CMD``, ``COPY LICENSE ./LICENSE``,
installs ``lumilake-sdk`` + ``lumilake-hook`` in-tree + flat
``requirements.txt`` generated by ``scripts/dev/sync_requirements.py``
(env-marker safe, fails loudly on unparsable specs).
CI consistency:
- All 9 ``setup-uv`` invocations now pin both ``version: "0.11.8"`` and
``python-version: "3.12"``.
- ``env-examples.yml`` adds ``--extra deploy`` so the script can
``import lumilake_deploy.doctor``.
- ``lint-typecheck.yml`` and ``unit-tests.yml`` add ``--frozen``.
- ``security.yml`` bandit scans every package source root +
``scripts/``; pip-audit splits into image-runtime (server
``requirements.txt``) and wheel-install closure
(``uv export --all-extras --no-default-groups
--no-emit-workspace``).
Docs:
- ``README.md`` Quick Start + Deployment, ``docs/CLI.md``, ``docs/ENV.md``,
``CONTRIBUTING.md`` consistently use ``lumilake deploy -C <path>``
(or ``LUMILAKE_DEPLOY_DIR``), with explicit ``uv run`` vs PyPI
install guidance.
- ``docs/ARCHITECTURE.md``, ``docs/OPS.md``, ``docs/PLUGINS.md``,
``docs/CODE_STYLE.md``, ``docs/SDK.md`` updated for the workspace
split (no more ``lumilake.{server,runtime,ops,utils,...}`` paths).
- PR template + repository-layout block updated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Zhengyuan Su <su.zhengyuan@u.nus.edu>
* ci: clear zizmor findings on image-publish.yml
Pedantic-persona zizmor (the form CI runs under
``--persona pedantic --format github``) was failing with two findings
on the image-publish workflow:
* ``cache-poisoning`` (high) — ``astral-sh/setup-uv`` enables its cache
by default. In a workflow that pushes signed artifacts to GHCR, a
poisoned cache could influence the publishing step. Set
``enable-cache: false`` on this workflow's setup-uv invocation; the
other setup-uv calls (lint, tests, env-examples, security, etc.)
aren't publishing workflows and keep caching for speed.
* ``undocumented-permissions`` (low) — ``packages: write`` at job
level had no explanatory comment. Added the same style of inline
comment release-images.yml already uses
(`docker/login-action + build-push-action push to GHCR`).
``zizmor --persona pedantic --format github`` exits 0 after the fix.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Zhengyuan Su <su.zhengyuan@u.nus.edu>
* patch image publish workflow
Signed-off-by: Zhengyuan Su <su.zhengyuan@u.nus.edu>
* docs: clarify image publish workflow
Signed-off-by: Zhengyuan Su <su.zhengyuan@u.nus.edu>
---------
Signed-off-by: Zhengyuan Su <su.zhengyuan@u.nus.edu>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 1c8db0d commit 9fb69b6
219 files changed
Lines changed: 4355 additions & 1069 deletions
File tree
- .github
- workflows
- docs
- examples/plugins/simple_plugin
- packages
- cli
- src/lumilake_cli
- commands
- core
- deploy
- src/lumilake_deploy
- assets
- hook
- src/lumilake_hook
- sdk
- src/lumilake
- resources
- scripts
- ci
- dev
- src
- lumilake_server
- graphs
- hooks
- ops
- parser
- routes
- runtime
- job_manager
- cluster_algo
- optimizer
- schedule
- runtime_manager
- utils
- schemas
- utils
- lumilake
- cli/commands
- graphs
- runtime
- utils
- sdk
- tests
- cli
- runtime
- job_manager
- optimizer
- runtime_manager
- flowmesh
- server
- sdk
- test_resources
- server
- parser
- support
- utils
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
This file was deleted.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | | - | |
23 | | - | |
| 22 | + | |
| 23 | + | |
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
25 | 26 | | |
26 | 27 | | |
27 | 28 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
| 36 | + | |
36 | 37 | | |
37 | 38 | | |
38 | | - | |
| 39 | + | |
39 | 40 | | |
40 | 41 | | |
41 | 42 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
29 | 30 | | |
30 | 31 | | |
31 | 32 | | |
32 | | - | |
| 33 | + | |
| 34 | + | |
33 | 35 | | |
34 | 36 | | |
35 | 37 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
| 36 | + | |
36 | 37 | | |
37 | 38 | | |
38 | | - | |
| 39 | + | |
39 | 40 | | |
40 | 41 | | |
41 | | - | |
| 42 | + | |
42 | 43 | | |
43 | 44 | | |
44 | 45 | | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
0 commit comments