mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 7. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/setup-python/releases">actions/setup-python's releases</a>.</em></p> <blockquote> <h2>v7.0.0</h2> <h2>What's Changed</h2> <h3>Enhancements</h3> <ul> <li>Migrate to ESM and upgrade dependencies by <a href="https://github.com/priyagupta108"><code>@priyagupta108</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1330">actions/setup-python#1330</a></li> <li>Pin SHA commits and update docs with latest versions by <a href="https://github.com/HarithaVattikuti"><code>@HarithaVattikuti</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1338">actions/setup-python#1338</a></li> <li>Remove the pip-install input by <a href="https://github.com/gowridurgad"><code>@gowridurgad</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1336">actions/setup-python#1336</a></li> </ul> <h3>Bug Fix</h3> <ul> <li>Fix to Classify stderr warning messages as warnings instead of errors in annotations by <a href="https://github.com/lmvysakh"><code>@lmvysakh</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1335">actions/setup-python#1335</a></li> <li>Validate and retry manifest fetch to prevent silent failures by <a href="https://github.com/priyagupta108"><code>@priyagupta108</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1332">actions/setup-python#1332</a></li> </ul> <h3>Dependency Upgrade</h3> <ul> <li>Bump certifi from 2020.6.20 to 2024.7.4 in /<strong>tests</strong>/data by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1328">actions/setup-python#1328</a></li> <li>Remove EOL Python versions and Bumps numpy text fixture by <a href="https://github.com/priya-kinthali"><code>@priya-kinthali</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1333">actions/setup-python#1333</a></li> <li>Upgrade <code>@actions/cache</code> to 6.2.0 by <a href="https://github.com/philip-gai"><code>@philip-gai</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1337">actions/setup-python#1337</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/lmvysakh"><code>@lmvysakh</code></a> made their first contribution in <a href="https://redirect.github.com/actions/setup-python/pull/1335">actions/setup-python#1335</a></li> <li><a href="https://github.com/philip-gai"><code>@philip-gai</code></a> made their first contribution in <a href="https://redirect.github.com/actions/setup-python/pull/1337">actions/setup-python#1337</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/setup-python/compare/v6...v7.0.0">https://github.com/actions/setup-python/compare/v6...v7.0.0</a></p> <h2>v6.3.0</h2> <h2>What's Changed</h2> <h3>Enhancement</h3> <ul> <li>Add RHEL support and include Linux distro in cache keys by <a href="https://github.com/priyagupta108"><code>@priyagupta108</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1323">actions/setup-python#1323</a></li> <li>Fix pip cache error handling on Windows by <a href="https://github.com/priyagupta108"><code>@priyagupta108</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1040">actions/setup-python#1040</a></li> </ul> <h3>Dependency update</h3> <ul> <li>Upgrade minimatch from 3.1.2 to 3.1.5 by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1281">actions/setup-python#1281</a></li> <li>Upgrade actions dependencies by <a href="https://github.com/gowridurgad"><code>@gowridurgad</code></a> with <a href="https://github.com/Copilot"><code>@Copilot</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1303">actions/setup-python#1303</a></li> <li>Upgrade <code>@actions/cache</code> to 5.1.0, log cache write denied by <a href="https://github.com/jasongin"><code>@jasongin</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1324">actions/setup-python#1324</a></li> <li>Upgrade dependency versions and test workflow configuration by <a href="https://github.com/HarithaVattikuti"><code>@HarithaVattikuti</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1322">actions/setup-python#1322</a></li> </ul> <h3>Documentation</h3> <ul> <li>Update advanced-usage.md by <a href="https://github.com/Dunky-Z"><code>@Dunky-Z</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/811">actions/setup-python#811</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/gowridurgad"><code>@gowridurgad</code></a> with <a href="https://github.com/Copilot"><code>@Copilot</code></a> made their first contribution in <a href="https://redirect.github.com/actions/setup-python/pull/1303">actions/setup-python#1303</a></li> <li><a href="https://github.com/jasongin"><code>@jasongin</code></a> made their first contribution in <a href="https://redirect.github.com/actions/setup-python/pull/1324">actions/setup-python#1324</a></li> <li><a href="https://github.com/Dunky-Z"><code>@Dunky-Z</code></a> made their first contribution in <a href="https://redirect.github.com/actions/setup-python/pull/811">actions/setup-python#811</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/setup-python/compare/v6.2.0...v6.3.0">https://github.com/actions/setup-python/compare/v6.2.0...v6.3.0</a></p> <h2>v6.2.0</h2> <h2>What's Changed</h2> <h3>Dependency Upgrades</h3> <ul> <li>Upgrade dependencies to Node 24 compatible versions by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/setup-python/pull/1259">actions/setup-python#1259</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="5fda3b95a4"><code>5fda3b9</code></a> Pin SHA commits and update docs with latest versions (<a href="https://redirect.github.com/actions/setup-python/issues/1338">#1338</a>)</li> <li><a href="4ab7e95f05"><code>4ab7e95</code></a> Merge pull request <a href="https://redirect.github.com/actions/setup-python/issues/1337">#1337</a> from actions/philip-gai/bump-actions-cache-6-2-0</li> <li><a href="0f3a009f47"><code>0f3a009</code></a> Remove the pip-install input (<a href="https://redirect.github.com/actions/setup-python/issues/1336">#1336</a>)</li> <li><a href="f8cf4291c8"><code>f8cf429</code></a> Migrate to ESM and upgrade dependencies (<a href="https://redirect.github.com/actions/setup-python/issues/1330">#1330</a>)</li> <li><a href="54baeea5b3"><code>54baeea</code></a> Validate and retry manifest fetch to prevent silent failures (<a href="https://redirect.github.com/actions/setup-python/issues/1332">#1332</a>)</li> <li><a href="c7092773a3"><code>c709277</code></a> Annotation code fix (<a href="https://redirect.github.com/actions/setup-python/issues/1335">#1335</a>)</li> <li><a href="6849080452"><code>6849080</code></a> remove EOL Python versions and Bumps numpy text fixture (<a href="https://redirect.github.com/actions/setup-python/issues/1333">#1333</a>)</li> <li><a href="0903b469fb"><code>0903b46</code></a> Bump certifi from 2020.6.20 to 2024.7.4 in /<strong>tests</strong>/data (<a href="https://redirect.github.com/actions/setup-python/issues/1328">#1328</a>)</li> <li><a href="ece7cb06ca"><code>ece7cb0</code></a> Fix pip cache error handling on Windows. (<a href="https://redirect.github.com/actions/setup-python/issues/1040">#1040</a>)</li> <li><a href="1d18d7af5f"><code>1d18d7a</code></a> Update advanced-usage.md (<a href="https://redirect.github.com/actions/setup-python/issues/811">#811</a>)</li> <li>Additional commits viewable in <a href="https://github.com/actions/setup-python/compare/v5...v7">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
263 lines
10 KiB
YAML
263 lines
10 KiB
YAML
name: rust
|
|
|
|
# Path gating lives in the `rust-changes` job below, NOT in a workflow-level
|
|
# `paths:` filter. The distinction matters for branch protection: a workflow
|
|
# skipped by `paths:` never creates its check runs at all, so a required status
|
|
# check from it sits pending forever on any PR that misses those paths, and the
|
|
# PR can never merge. A job skipped by `if:` still creates a check run, reports
|
|
# `skipped`, and GitHub counts skipped as success for a required check.
|
|
#
|
|
# Same coverage as the old filter — the path list moved verbatim into
|
|
# `rust-changes` — but `parity` is now safe to mark required on `main`.
|
|
on:
|
|
push:
|
|
branches: [ main, rust-rewrite ]
|
|
pull_request:
|
|
schedule:
|
|
# Nightly parity run at 07:17 UTC (weekdays only). Redundant with the
|
|
# per-PR gate below, but catches drift from toolchain/dependency updates
|
|
# that land without touching any filtered path.
|
|
- cron: '17 7 * * 1-5'
|
|
|
|
concurrency:
|
|
group: rust-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
# Default permissions: read-only. Individual jobs override only what they need.
|
|
# Mitigates CodeQL/CWE-275 (missing-workflow-permissions): the GITHUB_TOKEN
|
|
# defaults to whatever the repo policy is, which can be read-write. Pinning
|
|
# this here means even if the repo default changes, this workflow stays safe.
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
# Carries the path list the workflow-level `paths:` filter used to hold. Named
|
|
# `rust-changes` rather than `changes` so it does not collide with ci.yml's
|
|
# `changes` check.
|
|
rust-changes:
|
|
name: rust-changes
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
outputs:
|
|
rust: ${{ steps.decide.outputs.rust }}
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: dorny/paths-filter@v4
|
|
id: filter
|
|
if: github.event_name == 'pull_request' || github.event_name == 'push'
|
|
with:
|
|
filters: |
|
|
rust:
|
|
- 'crates/**'
|
|
- 'Cargo.toml'
|
|
- 'Cargo.lock'
|
|
- 'rust-toolchain.toml'
|
|
- 'tests/parity/**'
|
|
- 'Makefile'
|
|
- '.github/workflows/rust.yml'
|
|
- id: decide
|
|
# `schedule` and `workflow_dispatch` have no diff to filter against, so
|
|
# they run the full suite — that is the point of the nightly job.
|
|
run: |
|
|
case "${{ github.event_name }}" in
|
|
pull_request|push) echo "rust=${{ steps.filter.outputs.rust }}" >> "$GITHUB_OUTPUT" ;;
|
|
*) echo "rust=true" >> "$GITHUB_OUTPUT" ;;
|
|
esac
|
|
|
|
test:
|
|
name: test (ubuntu)
|
|
needs: rust-changes
|
|
if: needs.rust-changes.outputs.rust == 'true'
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- name: Install stable toolchain
|
|
# Pin action code to @stable (latest fixes), toolchain version
|
|
# via input. The @1.95.0 ref shipped action code that errors on
|
|
# ubuntu-latest with `detected conflict: 'bin/cargo-clippy'`
|
|
# because the pre-installed runner Rust collides with the
|
|
# clippy-preview component install.
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
toolchain: 1.95.0
|
|
components: rustfmt, clippy
|
|
- name: Cache cargo registry + build
|
|
uses: Swatinem/rust-cache@v2
|
|
- uses: actions/setup-python@v7
|
|
with:
|
|
python-version: '3.11'
|
|
- name: Provide ONNX Runtime dylib
|
|
# headroom-core is built with `ort-load-dynamic` (see its
|
|
# Cargo.toml): the ONNX Runtime shared library is dlopen'd at
|
|
# runtime instead of statically linked, so the magika/detection
|
|
# tests need a real libonnxruntime.so and ORT_DYLIB_PATH pointing
|
|
# at it — same contract `headroom/_ort.py` fulfills for Python
|
|
# users via the pip `onnxruntime` package.
|
|
run: |
|
|
# >= 1.24, not 1.16: `ort`'s ORT_API_VERSION resolves to 24 because
|
|
# `fastembed` enables its `api-24` feature.
|
|
pip install 'onnxruntime>=1.24'
|
|
# Pre-flight, not just a pin. `ort` deadlocks rather than errors on
|
|
# ANY failure inside `load_dylib_from_path` — a version mismatch and
|
|
# a library that cannot be resolved at all both re-enter the `Once`
|
|
# that `setup_api()` is initialising, and `std::sync::Once` blocks
|
|
# forever on re-entry. Either way the job burns its full 30-minute
|
|
# timeout at 0% CPU with nothing in the log. Assert both conditions
|
|
# here so a bad runner fails in seconds with a readable message.
|
|
python - <<'PY' >> "$GITHUB_ENV"
|
|
import pathlib, sys
|
|
|
|
def die(msg: str) -> None:
|
|
print(f"::error::{msg}", file=sys.stderr)
|
|
raise SystemExit(1)
|
|
|
|
try:
|
|
import onnxruntime
|
|
except Exception as exc: # noqa: BLE001 - any import failure is fatal here
|
|
die(f"onnxruntime is not importable: {exc}")
|
|
|
|
version = onnxruntime.__version__
|
|
try:
|
|
major, minor = (int(part) for part in version.split(".")[:2])
|
|
except ValueError:
|
|
die(f"cannot parse onnxruntime version {version!r}")
|
|
if (major, minor) < (1, 24):
|
|
die(
|
|
f"onnxruntime {version} is too old: ort requires >= 1.24 "
|
|
"(ORT_API_VERSION=24, set by fastembed's api-24 feature). "
|
|
"ort DEADLOCKS instead of erroring below this, so the tests "
|
|
"would hang rather than fail."
|
|
)
|
|
|
|
capi = pathlib.Path(onnxruntime.__file__).parent / "capi"
|
|
libs = sorted(capi.glob("libonnxruntime.so*")) or sorted(capi.glob("libonnxruntime*.dylib"))
|
|
if not libs:
|
|
die(f"no libonnxruntime shared library under {capi}")
|
|
|
|
print(f"ORT_DYLIB_PATH={libs[0]}")
|
|
print(f"onnxruntime {version} -> {libs[0]}", file=sys.stderr)
|
|
PY
|
|
- name: cargo fmt --check
|
|
run: cargo fmt --all -- --check
|
|
- name: cargo clippy
|
|
run: cargo clippy --workspace -- -D warnings
|
|
- name: cargo test
|
|
run: cargo test --workspace
|
|
|
|
simulator-e2e:
|
|
name: simulator e2e (${{ matrix.os }})
|
|
needs: rust-changes
|
|
if: needs.rust-changes.outputs.rust == 'true'
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 30
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- name: Install stable toolchain
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
toolchain: 1.95.0
|
|
- name: Cache cargo registry + build
|
|
uses: Swatinem/rust-cache@v2
|
|
- name: cargo test simulator-backed proxy e2e
|
|
run: cargo test -p headroom-proxy --test e2e_simulators
|
|
|
|
wheels:
|
|
name: wheels (${{ matrix.target }})
|
|
needs: rust-changes
|
|
if: needs.rust-changes.outputs.rust == 'true'
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 45
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: ubuntu-latest
|
|
target: x86_64-unknown-linux-gnu
|
|
maturin-target: x86_64
|
|
- os: macos-14
|
|
target: aarch64-apple-darwin
|
|
maturin-target: aarch64-apple-darwin
|
|
- os: macos-15-intel
|
|
target: x86_64-apple-darwin
|
|
maturin-target: x86_64-apple-darwin
|
|
# Intel macOS uses `ort-load-dynamic` (no prebuilt ORT from ort-sys);
|
|
# Apple Silicon bundles ORT via `ort-download-binaries-rustls-tls`.
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-python@v7
|
|
with:
|
|
python-version: '3.11'
|
|
- name: "Build wheel (single-wheel architecture builds headroom-ai)"
|
|
uses: PyO3/maturin-action@v1
|
|
# Maturin reads `[tool.maturin]` from the root `pyproject.toml`
|
|
# which points at `crates/headroom-py/Cargo.toml` for the cdylib.
|
|
# Output is `headroom_ai-<ver>-<py>-<py>-<platform>.whl` containing
|
|
# both Python source and the compiled `headroom/_core.so`.
|
|
with:
|
|
command: build
|
|
args: --release --out dist
|
|
target: ${{ matrix.maturin-target }}
|
|
- name: Upload wheel artifact
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: wheels-${{ matrix.target }}
|
|
path: dist/*.whl
|
|
|
|
audit:
|
|
name: audit
|
|
needs: rust-changes
|
|
if: needs.rust-changes.outputs.rust == 'true'
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
toolchain: 1.95.0
|
|
- uses: Swatinem/rust-cache@v2
|
|
- name: Install cargo-audit + cargo-deny
|
|
uses: taiki-e/install-action@v2
|
|
with:
|
|
tool: cargo-audit,cargo-deny
|
|
# Blocking. Soft-failing this made it useless: RUSTSEC-2026-0258 (h2,
|
|
# unbounded empty DATA frames -> unbounded memory or a panic) was
|
|
# reported by this job for as long as it existed and never turned a run
|
|
# red, so nobody acted on it. Accepted advisories go in audit.toml with
|
|
# a written reason rather than being swallowed wholesale here.
|
|
- name: cargo audit
|
|
run: cargo audit
|
|
- name: cargo deny check licenses
|
|
continue-on-error: true
|
|
run: cargo deny check licenses
|
|
|
|
# Blocking on every PR that touches Rust. Safe to harden now because the
|
|
# harness fails only on a Diff — `parity-run` sets `any_diffs` inside the
|
|
# diffed loop alone, so the 65 fixtures still served by `stub_comparator!`
|
|
# report as Skipped and cannot turn this red. Measured on main today:
|
|
# 111 matched / 65 skipped / 0 diffed.
|
|
#
|
|
# What it protects: the recorded fixtures are frozen Python output, so this
|
|
# gate catches the Rust side drifting away from that snapshot — exactly the
|
|
# failure mode the ongoing port produces. It cannot detect the Python side
|
|
# drifting away from the fixtures; that needs re-recording, not this job.
|
|
parity:
|
|
name: parity
|
|
needs: rust-changes
|
|
if: needs.rust-changes.outputs.rust == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
toolchain: 1.95.0
|
|
- uses: Swatinem/rust-cache@v2
|
|
# No Python toolchain: headroom-parity links headroom-core directly and
|
|
# never crosses into the interpreter, so the venv + maturin + `pip
|
|
# install -e .` setup this job used to do was pure overhead.
|
|
- name: Run parity harness
|
|
run: make test-parity
|