mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-18 02:00:48 +00:00
nodejs: lazy per-backend libsimplex download (#7543)
* ci: drop dlltool from nodejs libs release * nodejs: download libsimplex into the user cache * nodejs: load libsimplex at runtime per backend * support bot: select db backend with --db * python: match backend switch error text * nodejs: download prebuilt add-on at runtime * ci: build nodejs add-on for libs release * calculator bot: load libs and add-on in image * support bot: document add-on override * nodejs: keep worker test output free of colors * nodejs: verify sha-256 of downloaded assets * python: pin core libs release with sha-256 * ci: add packages release script * ci: release nodejs add-on and open release PR * ci: publish packages after release PR * nodejs: keep npm from building the add-on * calculator bot: build the add-on in the image * ci: merge package release workflows * ci: open release PR when publishing fails * ci: build the add-on with node-addon-api only * ci: skip publishing in a called packages workflow * ci: update package release actions to Node 24 * nodejs: fix receive test timeout * ci: test packages on pull requests * nodejs: reuse the database in the close stress test * ci: keep failed package tests from hanging * ci: skip preset server tests * ci: plan package builds from the changes * ci: test packages with a given libsimplex * ci: test packages with libsimplex of core changes
This commit is contained in:
@@ -7,6 +7,7 @@ from __future__ import annotations
|
||||
|
||||
import ctypes
|
||||
import errno
|
||||
import hashlib
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
@@ -18,7 +19,7 @@ from ctypes import POINTER, c_char_p, c_int, c_uint8, c_void_p
|
||||
from pathlib import Path
|
||||
from typing import Any, Literal
|
||||
|
||||
from ._version import LIBS_VERSION
|
||||
from ._version import LIBS_RELEASE, LIBS_SHA256
|
||||
|
||||
Backend = Literal["sqlite", "postgres"]
|
||||
|
||||
@@ -59,11 +60,14 @@ def _libname() -> str:
|
||||
return _LIBNAME[sys.platform]
|
||||
|
||||
|
||||
def _libs_url(backend: Backend) -> str:
|
||||
def _libs_asset(backend: Backend) -> str:
|
||||
suffix = "-postgres" if backend == "postgres" else ""
|
||||
return f"simplex-chat-libs-{_platform_tag()}{suffix}.zip"
|
||||
|
||||
|
||||
def _libs_url(backend: Backend) -> str:
|
||||
return (
|
||||
f"https://github.com/{_GITHUB_REPO}/releases/download/"
|
||||
f"v{LIBS_VERSION}/simplex-chat-libs-{_platform_tag()}{suffix}.zip"
|
||||
f"https://github.com/{_GITHUB_REPO}/releases/download/{LIBS_RELEASE}/{_libs_asset(backend)}"
|
||||
)
|
||||
|
||||
|
||||
@@ -84,7 +88,7 @@ def _resolve_libs_dir(backend: Backend) -> Path:
|
||||
"postgres backend is only supported on linux-x86_64; "
|
||||
f"current platform is {_platform_tag()}"
|
||||
)
|
||||
target = _cache_root() / f"v{LIBS_VERSION}" / backend
|
||||
target = _cache_root() / LIBS_RELEASE / backend
|
||||
if not (target / _libname()).exists():
|
||||
_download(target, backend)
|
||||
return target
|
||||
@@ -125,16 +129,21 @@ def _download(target: Path, backend: Backend) -> None:
|
||||
what we need and proceed. NEVER rmtree the target: that creates a TOCTOU
|
||||
window where another process is reading/loading the file we're deleting.
|
||||
"""
|
||||
asset = _libs_asset(backend)
|
||||
sha256 = LIBS_SHA256.get(asset)
|
||||
if sha256 is None:
|
||||
raise RuntimeError(f"no SHA-256 is pinned for {asset}")
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
url = _libs_url(backend)
|
||||
print(
|
||||
f"Downloading libsimplex ({_platform_tag()}, {backend}) v{LIBS_VERSION} from {url} ...",
|
||||
f"Downloading libsimplex ({_platform_tag()}, {backend}) {LIBS_RELEASE} from {url} ...",
|
||||
file=sys.stderr,
|
||||
flush=True,
|
||||
)
|
||||
with tempfile.TemporaryDirectory(dir=target.parent) as tmp:
|
||||
zip_path = Path(tmp) / "libs.zip"
|
||||
_stream_to_file(url, zip_path, timeout=60.0)
|
||||
_verify_sha256(zip_path, sha256, url)
|
||||
with zipfile.ZipFile(zip_path) as zf:
|
||||
zf.extractall(tmp)
|
||||
# zip layout: <tmp>/libs/libsimplex.* + libHS*.*
|
||||
@@ -158,6 +167,16 @@ def _download(target: Path, backend: Backend) -> None:
|
||||
) from e
|
||||
|
||||
|
||||
def _verify_sha256(file: Path, expected: str, url: str) -> None:
|
||||
digest = hashlib.sha256()
|
||||
with file.open("rb") as f:
|
||||
while chunk := f.read(_DOWNLOAD_CHUNK):
|
||||
digest.update(chunk)
|
||||
actual = digest.hexdigest()
|
||||
if actual != expected:
|
||||
raise RuntimeError(f"SHA-256 of {url} is {actual}, expected {expected}")
|
||||
|
||||
|
||||
_lock = threading.Lock()
|
||||
_lib: ctypes.CDLL | None = None
|
||||
_libc: ctypes.CDLL | None = None
|
||||
@@ -230,8 +249,8 @@ def lib_for(backend: Backend) -> ctypes.CDLL:
|
||||
if _lib is not None:
|
||||
if _backend != backend:
|
||||
raise RuntimeError(
|
||||
f"libsimplex already loaded with backend={_backend!r}; "
|
||||
f"cannot switch to {backend!r} in the same process"
|
||||
f"libsimplex already loaded with backend={_backend}; "
|
||||
f"cannot switch to {backend} in the same process"
|
||||
)
|
||||
return _lib
|
||||
libs_dir = _resolve_libs_dir(backend)
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
"""Single source of truth for both the Python package version and the
|
||||
simplex-chat-libs release tag we depend on.
|
||||
"""Package version and the simplex-chat-libs release it loads.
|
||||
|
||||
Bump both together for normal releases. For wrapper-only fixes use a PEP 440
|
||||
post-release: __version__ = "6.5.2.post1", LIBS_VERSION unchanged.
|
||||
Written by scripts/ci/packages_release.py: the release PR bumps the version
|
||||
and pins new library releases with the SHA-256 of their assets.
|
||||
"""
|
||||
|
||||
__version__ = "7.1.0b6" # PEP 440 — read by hatchling for wheel metadata
|
||||
LIBS_VERSION = "7.1.0-beta.6" # simplex-chat-libs release tag (no 'v' prefix)
|
||||
LIBS_RELEASE = "core-7.1.0.11" # simplex-chat-libs release tag
|
||||
LIBS_SHA256 = {
|
||||
"simplex-chat-libs-linux-aarch64.zip": "d66aa1b30b9fa20225dad8ef75a9c605961e1c0adde2ba0283e2fcac4e15d260",
|
||||
"simplex-chat-libs-linux-x86_64-postgres.zip": "925b3166f969b12082ff8ee659e5f2a9933fe40120deb80c9aa3002a5ba6c803",
|
||||
"simplex-chat-libs-linux-x86_64.zip": "dabad0824e8813ea4a084fbf37e1ba4cf6dcea9cd8ccadc521fec200f246208a",
|
||||
"simplex-chat-libs-macos-aarch64.zip": "aa74608b149fff7508a47eaac4284dcc6d189c6ed8b7c18428df9158bc176a61",
|
||||
"simplex-chat-libs-macos-x86_64.zip": "a0e21457e1077be7f71b46c1c27452945b2cee2b6c50efb0004412ce5b7042ec",
|
||||
"simplex-chat-libs-windows-x86_64.zip": "c01dad574daa101a1cbfd31ddbf2b3d0d986a4a42f97d789d2f878b2050b2b4b",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user