Skip to content

Commit 7d90321

Browse files
committed
Add PyPI release workflow with trusted publishing
- Add .github/workflows/release.yml for automated releases - Build frontend in CI (remove committed static assets) - Use uv publish with OIDC trusted publishing - Smoke test wheel and sdist before publishing - Trigger on v* tags and workflow_dispatch
1 parent ba5ddf9 commit 7d90321

42 files changed

Lines changed: 117 additions & 479 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*" # Publish on any tag starting with v, e.g., v0.1.0
7+
workflow_dispatch:
8+
9+
jobs:
10+
build:
11+
name: Build distributions
12+
runs-on: ubuntu-latest
13+
permissions:
14+
contents: read
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v6
18+
with:
19+
fetch-depth: 0 # Required for hatch-vcs
20+
21+
- name: Set up Python
22+
uses: actions/setup-python@v6
23+
with:
24+
python-version: "3.12"
25+
26+
- name: Install uv
27+
uses: astral-sh/setup-uv@v7
28+
with:
29+
enable-cache: true
30+
31+
# Build frontend
32+
- name: Set up Node.js
33+
uses: actions/setup-node@v4
34+
with:
35+
node-version: 20
36+
cache: npm
37+
cache-dependency-path: frontend/package-lock.json
38+
39+
- name: Build frontend
40+
run: |
41+
cd frontend
42+
npm ci
43+
npm run build
44+
rm -rf ../src/hyperview/server/static
45+
mkdir -p ../src/hyperview/server/static
46+
cp -r out/* ../src/hyperview/server/static/
47+
48+
# Build Python package (includes frontend assets)
49+
- name: Build
50+
run: uv build --no-sources
51+
52+
# Smoke test: verify the built package can be imported
53+
- name: Smoke test (wheel)
54+
run: |
55+
uv run --isolated --no-project --with dist/*.whl \
56+
python -c "import hyperview; print(f'hyperview {hyperview.__version__}')"
57+
58+
- name: Smoke test (sdist)
59+
run: |
60+
uv run --isolated --no-project --with dist/*.tar.gz \
61+
python -c "import hyperview; print(f'hyperview {hyperview.__version__}')"
62+
63+
- name: Upload dist artifacts
64+
uses: actions/upload-artifact@v5
65+
with:
66+
name: python-package-distributions
67+
path: dist/
68+
if-no-files-found: error
69+
70+
pypi:
71+
name: Publish to PyPI
72+
needs: build
73+
if: startsWith(github.ref, 'refs/tags/v')
74+
runs-on: ubuntu-latest
75+
environment:
76+
name: pypi
77+
url: https://pypi.org/p/hyperview
78+
permissions:
79+
id-token: write
80+
contents: read
81+
steps:
82+
- name: Download dist artifacts
83+
uses: actions/download-artifact@v6
84+
with:
85+
name: python-package-distributions
86+
path: dist/
87+
88+
- name: Install uv
89+
uses: astral-sh/setup-uv@v7
90+
with:
91+
enable-cache: true
92+
93+
- name: Publish to PyPI
94+
run: uv publish

.gitignore

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,8 @@ frontend/node_modules/
3131
frontend/.next/
3232
frontend/out/
3333

34-
# Bundled frontend in Python package (built with scripts/export_frontend.sh)
35-
# Not ignored - needed for pip install from git / sdist
36-
# src/hyperview/server/static/
34+
# Bundled frontend in Python package (built in CI during release)
35+
src/hyperview/server/static/
3736

3837
# Python package build
3938
dist/
@@ -71,4 +70,7 @@ TESTS.md
7170
AGENTS.md
7271
**/AGENTS.md
7372
.github/agents/
74-
.specstory/
73+
.specstory/
74+
75+
# Generated version file (hatch-vcs)
76+
src/hyperview/_version.py

pyproject.toml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[project]
22
name = "hyperview"
3-
version = "0.1.0"
3+
dynamic = ["version"]
44
description = "Open-source dataset curation with hyperbolic embeddings visualization"
55
readme = "README.md"
66
license = { text = "MIT" }
77
requires-python = ">=3.10"
88
authors = [
9-
{ name = "HyperView Team" }
9+
{ name = "hyper3labs" }
1010
]
1111
keywords = ["embeddings", "visualization", "hyperbolic", "dataset", "curation", "machine-learning"]
1212
classifiers = [
@@ -60,12 +60,18 @@ Repository = "https://github.com/Hyper3Labs/HyperView"
6060
Issues = "https://github.com/Hyper3Labs/HyperView/issues"
6161

6262
[build-system]
63-
requires = ["hatchling"]
63+
requires = ["hatchling", "hatch-vcs"]
6464
build-backend = "hatchling.build"
6565

6666
[tool.hatch.metadata]
6767
allow-direct-references = true
6868

69+
[tool.hatch.version]
70+
source = "vcs"
71+
72+
[tool.hatch.build.hooks.vcs]
73+
version-file = "src/hyperview/_version.py"
74+
6975
[tool.hatch.build.targets.wheel]
7076
packages = ["src/hyperview"]
7177
# Include frontend static assets (pre-built before packaging)

src/hyperview/__init__.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
"""HyperView - Open-source dataset curation with hyperbolic embeddings visualization."""
22

3-
from hyperview.api import Dataset, launch
4-
from hyperview.embeddings.engine import (
5-
EmbeddingSpec,
6-
get_provider_info,
7-
list_embedding_providers,
8-
)
3+
from . import _version as _version
4+
from . import api as _api
5+
6+
Dataset = _api.Dataset
7+
launch = _api.launch
8+
__version__ = _version.__version__
99

10-
__version__ = "0.1.0"
1110
__all__ = [
1211
"Dataset",
13-
"EmbeddingSpec",
14-
"get_provider_info",
1512
"launch",
16-
"list_embedding_providers",
1713
"__version__",
1814
]

src/hyperview/core/dataset.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ def compute_embeddings(
369369
hyper-models name (e.g. 'hycoclip-vit-s') for hyperbolic embeddings.
370370
provider: Explicit provider identifier. If not specified, auto-detected:
371371
'hyper-models' if model matches a hyper-models name, else 'embed-anything'.
372-
Available providers: `hyperview.list_embedding_providers()`.
372+
Available providers: `hyperview.embeddings.list_embedding_providers()`.
373373
checkpoint: Checkpoint path/URL (hf://... or local path) for weight-only models.
374374
batch_size: Batch size for processing.
375375
show_progress: Whether to show progress bar.
@@ -384,7 +384,7 @@ def compute_embeddings(
384384
if not model:
385385
raise ValueError(
386386
"model is required. Examples: 'openai/clip-vit-base-patch32' (CLIP), "
387-
"'hycoclip-vit-s' (hyperbolic). See hyperview.list_embedding_providers()."
387+
"'hycoclip-vit-s' (hyperbolic). See hyperview.embeddings.list_embedding_providers()."
388388
)
389389

390390
from hyperview.embeddings.engine import EmbeddingSpec

src/hyperview/server/static/404.html

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)