diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 9e5c321..c97e0a0 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -51,9 +51,23 @@ jobs: node-version: "20" cache: npm + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install npm dependencies run: npm ci + - name: Build Sigima wheel + run: | + python -m pip install "$(grep '^Babel' requirements-dev.txt)" + python scripts/build_sigima_wheel.py \ + "$(grep '^sigima @ ' requirements-dev.txt)" .wheels + wheel_path=$(find "$GITHUB_WORKSPACE/.wheels" -name 'sigima-*.whl' -print -quit) + test -n "$wheel_path" + echo "VITE_SIGIMA_INSTALL_SPEC=/@fs/$wheel_path" >> "$GITHUB_ENV" + - name: Install Playwright browser run: npx playwright install --with-deps chromium diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d789a55..cfcde9c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -77,9 +77,22 @@ jobs: node-version: 20 cache: npm + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install npm dependencies run: npm ci + - name: Build Sigima wheel + run: | + python -m pip install "$(grep '^Babel' requirements-dev.txt)" + python scripts/build_sigima_wheel.py \ + "$(grep '^sigima @ ' requirements-dev.txt)" .wheels + wheel_path=$(find "$GITHUB_WORKSPACE/.wheels" -name 'sigima-*.whl' -print -quit) + test -n "$wheel_path" + echo "VITE_SIGIMA_INSTALL_SPEC=/@fs/$wheel_path" >> "$GITHUB_ENV" + - name: Install Playwright browsers run: npx playwright install --with-deps chromium diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6f1d94e..b11a44c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -93,9 +93,23 @@ jobs: node-version: "20" cache: npm + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install npm dependencies run: npm ci + - name: Build Sigima wheel + run: | + python -m pip install "$(grep '^Babel' requirements-dev.txt)" + python scripts/build_sigima_wheel.py \ + "$(grep '^sigima @ ' requirements-dev.txt)" .wheels + wheel_path=$(find "$GITHUB_WORKSPACE/.wheels" -name 'sigima-*.whl' -print -quit) + test -n "$wheel_path" + echo "VITE_SIGIMA_INSTALL_SPEC=/@fs/$wheel_path" >> "$GITHUB_ENV" + - name: Install Playwright browsers run: npx playwright install --with-deps chromium diff --git a/requirements-dev.txt b/requirements-dev.txt index c320e39..109e43f 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -9,6 +9,7 @@ # Core test runner and coverage tooling. pytest>=7.4 pytest-cov>=4.1 +Babel>=2.17 # Linters / formatters used by the VS Code tasks (Ruff + Pylint). ruff>=0.5 @@ -19,8 +20,8 @@ pylint>=3.0 pre-commit>=3.7 # Sigima (= computation engine) and its mandatory dependencies. -# Pinning floors only — exact versions come from each project's pyproject. -sigima>=1.3.0 +# Pin the unreleased revision that provides the annotation APIs used here. +sigima @ https://github.com/DataLab-Platform/Sigima/archive/4442ada873655f63fabd14369fd11170f75a28b4.zip guidata>=3.15.0 numpy>=1.22 scipy>=1.10.1 diff --git a/scripts/build_sigima_wheel.py b/scripts/build_sigima_wheel.py new file mode 100644 index 0000000..ec9b191 --- /dev/null +++ b/scripts/build_sigima_wheel.py @@ -0,0 +1,84 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Build a Sigima source requirement with compiled gettext catalogs.""" + +from __future__ import annotations + +import argparse +import shutil +import subprocess +import sys +import tempfile +from pathlib import Path + + +def run(*args: str) -> None: + """Run a Python module command with the active interpreter.""" + subprocess.run([sys.executable, *args], check=True) + + +def build_wheel(requirement: str, wheel_dir: Path) -> Path: + """Build *requirement* into *wheel_dir* after compiling translations.""" + wheel_dir.mkdir(parents=True, exist_ok=True) + with tempfile.TemporaryDirectory(prefix="sigima-wheel-") as tmp: + workspace = Path(tmp) + downloads = workspace / "downloads" + downloads.mkdir() + run( + "-m", + "pip", + "download", + "--no-deps", + "--no-binary=:all:", + "--dest", + str(downloads), + requirement, + ) + + archives = list(downloads.iterdir()) + if len(archives) != 1: + raise RuntimeError(f"Expected one Sigima archive, found {len(archives)}") + source_tree = workspace / "source" + shutil.unpack_archive(archives[0], source_tree) + + projects = list(source_tree.glob("*/pyproject.toml")) + if len(projects) != 1: + raise RuntimeError(f"Expected one Sigima project, found {len(projects)}") + project = projects[0].parent + locale_dir = project / "sigima" / "locale" + run( + "-m", + "babel.messages.frontend", + "compile", + "--directory", + str(locale_dir), + "--domain", + "sigima", + ) + run( + "-m", + "pip", + "wheel", + "--no-deps", + "--wheel-dir", + str(wheel_dir), + str(project), + ) + + wheels = list(wheel_dir.glob("sigima-*.whl")) + if len(wheels) != 1: + raise RuntimeError(f"Expected one Sigima wheel, found {len(wheels)}") + return wheels[0] + + +def main() -> None: + """Build a wheel from the requested Sigima source revision.""" + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("requirement", help="PEP 508 Sigima source requirement") + parser.add_argument("wheel_dir", type=Path, help="Output wheel directory") + args = parser.parse_args() + print(build_wheel(args.requirement, args.wheel_dir)) + + +if __name__ == "__main__": + main()