Skip to content

build(deps): bump pyo3 from 0.29.0 to 0.29.2 in /ext #162

build(deps): bump pyo3 from 0.29.0 to 0.29.2 in /ext

build(deps): bump pyo3 from 0.29.0 to 0.29.2 in /ext #162

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
test:
name: test (py${{ matrix.python }} / ${{ matrix.os }})
strategy:
fail-fast: false
matrix:
python: ["3.12", "3.13", "3.14"]
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7.0.1
- uses: actions/setup-python@v7.0.0
with:
python-version: ${{ matrix.python }}
allow-prereleases: true
- name: Install pytest + cryptography (zerotrust optional dep, used by tests)
run: pip install --upgrade pip && pip install pytest cryptography
- name: Run tests
run: PYTHONPATH=lib pytest -q
shellcheck:
name: shellcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
- name: Run shellcheck
run: |
shellcheck hooks/scripts/*.sh
shellcheck install.sh
ascii:
name: ascii check (unicode)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
- name: Reject non-ASCII outside the intentional unicode test fixtures
# Enforces CONTRIBUTING hard constraints #2 (ASCII-only) and #3 (no
# em-dashes). git grep -P exits 0 when it finds a match, so a match
# means the build fails. The three fixtures are deliberate unicode.
run: |
if git grep -nP '[^\x00-\x7F]' -- \
':!tests/test_model.py' ':!tests/test_redact.py' ':!tests/test_crypto.py'; then
echo "::error::non-ASCII characters found above; the project is ASCII-only outside tests/test_{model,redact,crypto}.py. Use '--' instead of em-dashes."
exit 1
fi
ruff:
name: ruff (python lint)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.13"
- name: Install ruff
run: pip install --upgrade pip && pip install ruff
- name: Run ruff
run: ruff check lib tests bench
bandit:
name: bandit (python security scan)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.13"
- name: Install bandit
run: pip install --upgrade pip && pip install "bandit[toml]"
- name: Run bandit
run: bandit -c pyproject.toml -r lib
coverage:
name: coverage (statement)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.13"
- name: Install pytest + cryptography + coverage
run: pip install --upgrade pip && pip install pytest cryptography coverage
- name: Run tests under coverage
# In-process measurement (deterministic). The hooks are unit-tested
# in-process; daemon.py is omitted (see pyproject [tool.coverage.run])
# since it only runs as a subprocess. No COVERAGE_PROCESS_START / combine.
run: PYTHONPATH=lib coverage run -m pytest -q
- name: Report (gate 74%, Silver target 80% tracked in #39)
run: coverage report --fail-under=74
manifest-integrity:
name: regenerate MANIFEST.lock
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.13"
- name: Regenerate MANIFEST.lock
run: PYTHONPATH=lib python lib/integrity.py --write
- name: Diff MANIFEST.lock
run: |
if ! git diff --exit-code MANIFEST.lock; then
echo "::error::MANIFEST.lock is stale. Run 'PYTHONPATH=lib python lib/integrity.py --write' and commit."
exit 1
fi
bench:
name: bench (perf regression gate)
runs-on: ubuntu-latest
# Single matrix cell to keep cost down. macOS bench numbers vary too much
# across hosted runners to be useful as a gate. Thresholds set with 2-3x
# headroom over local Python 3.14.4 numbers (cold ~80 ms, aggregate ~6.4 s);
# CI Linux is typically 1.5-2x slower. Bumping the thresholds is a
# deliberate, reviewable change.
steps:
- uses: actions/checkout@v7.0.1
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.13"
- name: Install pytest + cryptography
run: pip install --upgrade pip && pip install pytest cryptography
- name: Run cold_startup bench (threshold 300 ms median)
env:
THRESHOLD_MS: "300"
run: |
python3 bench/cold_startup.py --runs 20 | tee /tmp/bench-cold.txt
python3 - <<'PY'
import json, os, pathlib, sys
text = pathlib.Path('/tmp/bench-cold.txt').read_text()
lines = text.splitlines()
start = next(i for i, ln in enumerate(lines) if ln.startswith('{'))
parsed = json.loads('\n'.join(lines[start:]))
median = parsed['summary']['median_ms']
threshold = float(os.environ['THRESHOLD_MS'])
print(f'cold_startup median_ms = {median} (threshold {threshold})')
if median > threshold:
print(f'::error::cold_startup median {median} exceeded {threshold} ms threshold')
sys.exit(1)
PY
- name: Run aggregate_session bench (threshold 12000 ms median)
env:
THRESHOLD_MS: "12000"
run: |
python3 bench/aggregate_session.py --runs 5 | tee /tmp/bench-agg.txt
python3 - <<'PY'
import json, os, pathlib, sys
text = pathlib.Path('/tmp/bench-agg.txt').read_text()
lines = text.splitlines()
start = next(i for i, ln in enumerate(lines) if ln.startswith('{'))
parsed = json.loads('\n'.join(lines[start:]))
median = parsed['summary']['median_ms']
threshold = float(os.environ['THRESHOLD_MS'])
print(f'aggregate_session median_ms = {median} (threshold {threshold})')
if median > threshold:
print(f'::error::aggregate_session median {median} exceeded {threshold} ms threshold')
sys.exit(1)
PY
wheel-build:
# Catches pyo3 / pyext-feature-gated dep bumps that the binary build misses.
# Existing CI compiles only `presence-client` with --no-default-features
# (which excludes pyo3); this job compiles the wheel via maturin and smoke-
# tests it. PR #17 (pyo3 0.21 -> 0.24, broken Bound API) green-lit on every
# other job; this is the gate that would have caught it.
name: wheel build (${{ matrix.os }})
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7.0.1
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.13"
- uses: dtolnay/rust-toolchain@stable
- name: Install Linux system libraries
# Mirrors release.yml; libgit2-sys + secret-service need these on bare
# ubuntu-latest. macOS uses Apple frameworks via the SDK so no apt step.
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
pkg-config libssh2-1-dev libssl-dev zlib1g-dev
- name: Cache cargo registry + ext target
uses: actions/cache@v6.1.0
with:
path: |
~/.cargo/registry
~/.cargo/git
ext/target
key: wheel-build-${{ matrix.os }}-${{ hashFiles('ext/Cargo.lock') }}
- name: Install maturin
run: pip install --upgrade pip && pip install maturin
- name: Build wheel
run: cd ext && maturin build --release --out target/wheels
- name: Smoke-test the wheel
# Install + import + one function call. Catches dynamic-link / ABI
# mismatches that compile time misses. The runner's checkout is a git
# repo so get_head_commit returns a dict; the `is None` allowance
# documents the contract without being brittle.
run: |
WHEEL=$(find ext/target/wheels -name '*.whl' -type f | head -1)
pip install --force-reinstall --break-system-packages "$WHEEL"
python3 -c "
import presence_ext
head = presence_ext.git.get_head_commit('.')
assert head is None or 'sha' in head, f'unexpected get_head_commit shape: {head}'
print('wheel smoke-test ok')
"