Skip to content

Moss transcribe diarize #223

Moss transcribe diarize

Moss transcribe diarize #223

name: python-bindings
# The EVERY-PR gate for the PYTHON binding:
# - lint: generated-FFI drift gate (also regenerates the
# binding-neutral include/transcribe.abihash) +
# version-sync across the sources of truth.
# - python-shared: a shared libtranscribe, the pure-C api_smoke as an
# exported-symbol canary, and the Python test suite (model
# tests un-skip when the canary GGUFs are fetchable).
#
# The binding-agnostic native gates (cpp-tests, cpp-tests-sanitized,
# provider-dl-vulkan, link-smoke, posture-lint) moved to native-ci.yml
# (2026-06-13, bindings-shared-infra): they certify the C contracts EVERY
# binding relies on, not just Python's. Job names were preserved across
# the move.
#
# The full WHEEL matrix (python-wheels.yml) deliberately does NOT run per PR:
# it runs on workflow_dispatch and on every publish (rehearsal or release).
# This workflow plus native-ci.yml is what must stay green on every change.
on:
push:
branches: [main]
paths:
- "bindings/python/**"
- "include/**"
- "src/**"
- "scripts/lib/**"
- "tests/**"
- "ggml/**"
- "CMakeLists.txt"
- ".github/workflows/python-bindings.yml"
- ".github/actions/**"
- "scripts/ci/vulkan_degradation_check.py"
pull_request:
paths:
- "bindings/python/**"
- "include/**"
- "src/**"
- "scripts/lib/**"
- "tests/**"
- "ggml/**"
- "CMakeLists.txt"
- ".github/workflows/python-bindings.yml"
- ".github/actions/**"
- "scripts/ci/vulkan_degradation_check.py"
workflow_dispatch:
# The generated FFI layer is pinned to one libclang so the drift gate's embedded
# `libclang: <version>` line is reproducible across runs.
env:
LIBCLANG_PIN: "libclang==18.1.1"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
# Idle-friendly job on the Hetzner box (free); falls back to nothing —
# an offline box fails bounded via the timeout. BEFORE the repo goes
# public: move PR-triggered self-hosted jobs to hosted runners or gate
# them on non-PR events (fork PRs + self-hosted = code exec on the box).
runs-on: [self-hosted, Linux, X64, hetzner]
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- uses: astral-sh/setup-uv@v8.2.0
- name: Install clang (libclang resource-dir headers)
# Idempotent for the persistent self-hosted box: install once, no-op
# after (and no sudo needed when clang is already present).
run: |
command -v clang >/dev/null || \
{ sudo apt-get update && sudo apt-get install -y clang; }
- name: Generated-FFI drift gate
run: |
uv run --no-project --with "$LIBCLANG_PIN" \
bindings/python/_generate/generate.py --check
- name: Version sync (header / pyproject / __init__)
run: uv run --no-project bindings/python/_generate/check_version_sync.py
- name: GGUF writer layout
run: uv run scripts/lib/test_gguf_writer.py
python-shared:
runs-on: blacksmith-2vcpu-ubuntu-2404
env:
HF_TOKEN: ${{ secrets.HF_TOKEN }}
steps:
- uses: actions/checkout@v6
- uses: astral-sh/setup-uv@v8.2.0
- name: Install build deps
run: sudo apt-get update && sudo apt-get install -y cmake ninja-build ccache
- name: CPU ISA signature (segregates ccache across the heterogeneous fleet)
# ggml builds with -march=native here (the dev posture under test);
# ccache hashes the literal flag, not the ISA it resolves to, so a
# cache compiled on a richer CPU SIGILLs on a weaker one. Key the
# cache by the CPU's feature flags instead.
run: echo "CPU_SIG=$(grep -m1 '^flags' /proc/cpuinfo | sha256sum | cut -c1-8)" >> "$GITHUB_ENV"
- name: ccache (compile cache across runs)
uses: actions/cache@v5
with:
path: ~/.cache/ccache
key: ccache-shared-${{ env.CPU_SIG }}-${{ github.sha }}
restore-keys: ccache-shared-${{ env.CPU_SIG }}-
# Shared build in the official-wheel posture (no OpenMP / system BLAS), so
# the canary exercises the same configuration the provider wheels ship.
- name: Configure (shared, wheel posture)
run: |
cmake -B build-shared -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DTRANSCRIBE_BUILD_SHARED=ON \
-DTRANSCRIBE_USE_OPENMP=OFF \
-DTRANSCRIBE_USE_SYSTEM_BLAS=OFF \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- name: Build
run: cmake --build build-shared -j
- name: api_smoke (exported-symbol canary) + extension umbrella
run: ctest --test-dir build-shared --output-on-failure
# The canary model upgrades this lane from "imports and ABI" to a real
# end-to-end transcription. Guarded on HF_TOKEN (the model repo is
# private for now; forks have no token) — without it the model tests
# skip cleanly, exactly as before.
- uses: ./.github/actions/fetch-canary
with:
hf-token: ${{ secrets.HF_TOKEN }}
- name: Python tests (real transcription when the canary is present)
run: |
# libtranscribe.so is dlopen'd by ctypes; help it resolve its sibling
# ggml shared libs in the build tree.
export LD_LIBRARY_PATH="$(find "$PWD/build-shared" -name '*.so' \
-printf '%h\n' | sort -u | tr '\n' ':')$LD_LIBRARY_PATH"
# The loader auto-discovers build-shared/src/libtranscribe.so from the
# repo root; the TRANSCRIBE_SMOKE_* vars (exported by fetch-canary
# when HF_TOKEN exists) un-skip the offline AND streaming model
# tests. The prompted (nemotron) streaming test still skips here —
# its regression is pinned in CI by the sanitized C-level test.
uv run --project bindings/python --extra test \
pytest bindings/python/tests -q -rs