Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## [0.4.8] - 2026-05-19 - Video input broadening and wire safety
## [0.4.9] - 2026-05-19 - Video input broadening and wire safety

### Added

Expand All @@ -24,6 +24,10 @@
to stderr; subsequent frames are silently clamped.
- `stream_camera` raises `PlexusError` synchronously (before spawning a thread)
when FFmpeg is not found, rather than silently dying in the background.
- Minimum `requests` bumped to `>=2.32.4` (fixes CVE in `extract_zipped_paths`).
- Minimum `Pillow` bumped to `>=11.2.1` (fixes OOB write, FITS decompression bomb,
font integer overflow, PDF parsing DoS).
- Dropped Python 3.8 support (EOL October 2024); minimum is now Python 3.9.

## [0.4.7] - 2026-05-14 - Video streaming API

Expand Down
2 changes: 1 addition & 1 deletion plexus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
from plexus.client import Plexus, read_mjpeg_frames
from plexus.ws import WebSocketTransport

__version__ = "0.4.8"
__version__ = "0.4.9"
__all__ = ["Plexus", "WebSocketTransport", "read_mjpeg_frames"]
11 changes: 5 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ build-backend = "hatchling.build"

[project]
name = "plexus-python"
version = "0.4.8"
version = "0.4.9"
description = "Thin Python SDK for Plexus — send telemetry in one line"
readme = "README.md"
license = "Apache-2.0"
requires-python = ">=3.8"
requires-python = ">=3.9"
authors = [
{ name = "Plexus", email = "hello@plexus.dev" }
]
Expand All @@ -19,7 +19,6 @@ classifiers = [
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand All @@ -28,13 +27,13 @@ classifiers = [
"Topic :: System :: Hardware",
]
dependencies = [
"requests>=2.28.0",
"requests>=2.32.4",
"websocket-client>=1.7",
]

[project.optional-dependencies]
video = ["Pillow>=9.0"]
dev = ["pytest", "pytest-cov", "ruff", "websockets>=12"]
video = ["Pillow>=11.2.1"]
dev = ["pytest>=8.3.5", "pytest-cov", "ruff", "websockets>=12"]

[project.scripts]
plexus = "plexus.cli:main"
Expand Down
61 changes: 61 additions & 0 deletions scripts/release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/bash
# Usage: ./scripts/release.sh <version>
# Example: ./scripts/release.sh 0.4.8
#
# Extracts the matching section from CHANGELOG.md and creates a GitHub release.
# The publish workflow fires automatically and pushes to PyPI.

set -euo pipefail

VERSION=${1:-}
if [[ -z "$VERSION" ]]; then
echo "Usage: $0 <version> (e.g. $0 0.4.8)" >&2
exit 1
fi

# Verify the version exists in CHANGELOG.md
if ! grep -q "## \[$VERSION\]" CHANGELOG.md; then
echo "Error: no entry for [$VERSION] found in CHANGELOG.md" >&2
exit 1
fi

# Verify pyproject.toml version matches
CODE_VERSION=$(python3 -c "
import re
with open('pyproject.toml') as f:
m = re.search(r'^version\s*=\s*\"(.+?)\"', f.read(), re.MULTILINE)
print(m.group(1))
")
if [[ "$CODE_VERSION" != "$VERSION" ]]; then
echo "Error: pyproject.toml has version $CODE_VERSION, expected $VERSION" >&2
exit 1
fi

# Extract release title suffix (the part after the date, e.g. "Video input broadening and wire safety")
TITLE_SUFFIX=$(grep "## \[$VERSION\]" CHANGELOG.md | sed 's/.*[0-9] - //')

# Extract just the changelog section for this version
NOTES=$(python3 -c "
import re, sys
txt = open('CHANGELOG.md').read()
m = re.search(r'## \[$VERSION\].*?(?=\n## \[|\Z)', txt, re.DOTALL)
if not m:
sys.exit(1)
sys.stdout.write(m.group(0).strip())
" VERSION="$VERSION")

echo "Creating release v$VERSION — $TITLE_SUFFIX"
echo "---"
echo "$NOTES"
echo "---"
read -p "Proceed? [y/N] " confirm
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
echo "Aborted." >&2
exit 1
fi

gh release create "v$VERSION" \
--title "$VERSION — $TITLE_SUFFIX" \
--notes "$NOTES"

echo "Release v$VERSION created. PyPI publish workflow is running."
Loading
Loading