Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
7238b6e
chore(registry): publish marketplace registry update (#283)
streamkit-bot Apr 11, 2026
520ea73
feat(e2e): add headless pipeline validation tests
streamkit-devin Apr 11, 2026
8959b2f
refactor(e2e): restructure test pipelines to one-dir-per-test layout
streamkit-devin Apr 11, 2026
4cc3bd5
feat(e2e): add SVT-AV1 test pipeline and CI integration
streamkit-devin Apr 11, 2026
995175e
fix(ci): fail explicitly when skit server doesn't start
streamkit-devin Apr 11, 2026
c910178
feat(e2e): add complete format coverage for pipeline validation tests
streamkit-devin Apr 11, 2026
01e3a36
chore: add REUSE/SPDX license files for test audio fixtures
streamkit-devin Apr 11, 2026
50c738e
feat(ci): add GPU pipeline validation job on self-hosted runner
streamkit-devin Apr 11, 2026
37cb827
fix(ci): use alternate port for GPU pipeline validation server
streamkit-devin Apr 11, 2026
c96760b
fix(ci): add libssl-dev for GPU pipeline validation runner
streamkit-devin Apr 11, 2026
2c9933f
fix(test): correct multipart field name and audio channel config
streamkit-devin Apr 11, 2026
b97660d
fix(test): use mono audio fixtures to match Opus encoder pin type
streamkit-devin Apr 11, 2026
ce7b52e
fix(ci): add cleanup step to kill skit on self-hosted runner
streamkit-devin Apr 11, 2026
93cb983
fix(test): remove incompatible audio decode pipelines and fix GPU cle…
streamkit-devin Apr 11, 2026
e69cb9f
feat(ci): enable nvcodec + vulkan_video in GPU pipeline validation
streamkit-devin Apr 11, 2026
b8f3863
fix(test): correct doc comment for multipart field name
streamkit-devin Apr 11, 2026
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
172 changes: 172 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,178 @@ env:
RUSTC_WRAPPER: sccache

jobs:
pipeline-validation:
name: Pipeline Validation
runs-on: ubuntu-22.04
steps:
- name: Free disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
android: true
dotnet: true
haskell: true
large-packages: false
docker-images: true
swap-storage: false

- uses: actions/checkout@v5

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.5"

- name: Build UI
working-directory: ./ui
run: |
bun install --frozen-lockfile
bun run build

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.92.0"

- uses: mozilla-actions/sccache-action@v0.0.9

- uses: Swatinem/rust-cache@v2

- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y libvpx-dev nasm cmake ninja-build yasm meson ffmpeg

- name: Build and install SVT-AV1 from source (v4.1.0)
run: |
cd /tmp
git clone --depth 1 --branch v4.1.0 https://gitlab.com/AOMediaCodec/SVT-AV1.git
cd SVT-AV1
cmake -S . -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local
cmake --build build -j"$(nproc)"
sudo cmake --install build
sudo ldconfig

- name: Build skit
run: cargo build -p streamkit-server --bin skit --features "svt_av1 dav1d_static"

- name: Start skit server
run: |
SK_SERVER__ADDRESS=127.0.0.1:4545 ./target/debug/skit &
# Wait for the server to be healthy
HEALTHY=0
for i in $(seq 1 30); do
if curl -sf http://127.0.0.1:4545/healthz > /dev/null 2>&1; then
echo "skit is healthy"
HEALTHY=1
break
fi
sleep 1
done
if [ "$HEALTHY" -ne 1 ]; then
echo "ERROR: skit did not become healthy within 30s"
exit 1
fi

- name: Run pipeline validation tests (SW codecs only)
run: |
cd tests/pipeline-validation
PIPELINE_TEST_URL=http://127.0.0.1:4545 cargo test --test validate

pipeline-validation-gpu:
name: Pipeline Validation (GPU)
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
runs-on: self-hosted
steps:
- uses: actions/checkout@v5

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.5"

- name: Build UI
working-directory: ./ui
run: |
bun install --frozen-lockfile
bun run build

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.92.0"

- uses: mozilla-actions/sccache-action@v0.0.9

- uses: Swatinem/rust-cache@v2

- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y libvpx-dev nasm cmake ninja-build yasm meson ffmpeg libopus-dev pkg-config libssl-dev

- name: Build and install SVT-AV1 from source (v4.1.0)
run: |
cd /tmp
if pkg-config --atleast-version=2.0.0 SvtAv1Enc 2>/dev/null; then
echo "SVT-AV1 already installed, skipping build"
else
rm -rf SVT-AV1
git clone --depth 1 --branch v4.1.0 https://gitlab.com/AOMediaCodec/SVT-AV1.git
cd SVT-AV1
cmake -S . -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local
cmake --build build -j"$(nproc)"
sudo cmake --install build
sudo ldconfig
fi

- name: Build skit (with GPU + HW codecs + SVT-AV1 + dav1d)
env:
VPX_LIB_DIR: /usr/lib/x86_64-linux-gnu
VPX_INCLUDE_DIR: /usr/include
VPX_VERSION: "1.13.0"
CUDA_INCLUDE_PATH: /usr/include
# bindgen (used by shiguredo_nvcodec) needs the clang builtin include
# path so it can find stddef.h and other compiler-provided headers.
BINDGEN_EXTRA_CLANG_ARGS: "-I/usr/lib/llvm-18/lib/clang/18/include"
run: |
cargo build -p streamkit-server --bin skit --features "gpu nvcodec vulkan_video svt_av1 dav1d_static"

- name: Start skit server
run: |
# Use a non-default port to avoid conflicts with any persistent skit
# instance that may be running on the self-hosted runner.
SKIT_PORT=4546
SK_SERVER__ADDRESS=127.0.0.1:${SKIT_PORT} ./target/debug/skit &
echo $! > /tmp/skit-gpu.pid
# Wait for the server to be healthy
HEALTHY=0
for i in $(seq 1 30); do
if curl -sf http://127.0.0.1:${SKIT_PORT}/healthz > /dev/null 2>&1; then
echo "skit is healthy on port ${SKIT_PORT}"
HEALTHY=1
break
fi
sleep 1
done
if [ "$HEALTHY" -ne 1 ]; then
echo "ERROR: skit did not become healthy within 30s"
exit 1
fi

- name: Run pipeline validation tests (all codecs including GPU)
run: |
cd tests/pipeline-validation
PIPELINE_TEST_URL=http://127.0.0.1:4546 cargo test --test validate

- name: Stop skit server
if: always()
run: |
if [ -f /tmp/skit-gpu.pid ]; then
kill "$(cat /tmp/skit-gpu.pid)" 2>/dev/null || true
rm -f /tmp/skit-gpu.pid
fi

e2e:
name: Playwright E2E
runs-on: ubuntu-22.04
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/marketplace-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ jobs:
'--target', os.environ.get('GITHUB_SHA', 'HEAD'),
'--title', release_name,
'--notes', f'Plugin bundle for {name} v{version}.',
'--latest=false',
bundle,
]
if is_prerelease:
Expand Down
14 changes: 14 additions & 0 deletions dist/registry/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,20 @@
}
]
},
{
"id": "parakeet",
"name": "Parakeet TDT",
"description": "Fast speech-to-text using NVIDIA Parakeet TDT via sherpa-onnx",
"latest": "0.1.0",
"versions": [
{
"version": "0.1.0",
"manifest_url": "https://streamkit.dev/registry/plugins/parakeet/0.1.0/manifest.json",
"signature_url": "https://streamkit.dev/registry/plugins/parakeet/0.1.0/manifest.minisig",
"published_at": "2026-04-10"
}
]
},
{
"id": "piper",
"name": "Piper",
Expand Down
57 changes: 57 additions & 0 deletions dist/registry/plugins/parakeet/0.1.0/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"schema_version": 1,
"id": "parakeet",
"name": "Parakeet TDT",
"version": "0.1.0",
"node_kind": "parakeet",
"kind": "native",
"description": "Fast speech-to-text using NVIDIA Parakeet TDT via sherpa-onnx",
"license": "MPL-2.0",
"homepage": "https://huggingface.co/nvidia/parakeet-tdt-0.6b-v2",
"entrypoint": "libparakeet.so",
"bundle": {
"url": "https://github.com/streamer45/streamkit/releases/download/plugin-parakeet-v0.1.0/parakeet-0.1.0-bundle.tar.zst",
"sha256": "9ca3cd97ba3c665517dd1319f8492c15b6b97549231577b640bbbc0f71aa60c3",
"size_bytes": 15635462
},
"models": [
{
"id": "parakeet-tdt-0.6b-v2-int8",
"name": "Parakeet TDT 0.6B v2 (English, INT8)",
"default": true,
"source": "huggingface",
"repo_id": "streamkit/parakeet-models",
"revision": "main",
"files": [
"encoder.int8.onnx",
"decoder.int8.onnx",
"joiner.int8.onnx",
"tokens.txt"
],
"expected_size_bytes": 661190513,
"license": "CC-BY-4.0",
"license_url": "https://huggingface.co/nvidia/parakeet-tdt-0.6b-v2",
"file_checksums": {
"encoder.int8.onnx": "a32b12d17bbbc309d0686fbbcc2987b5e9b8333a7da83fa6b089f0a2acd651ab",
"decoder.int8.onnx": "b6bb64963457237b900e496ee9994b59294526439fbcc1fecf705b31a15c6b4e",
"joiner.int8.onnx": "7946164367946e7f9f29a122407c3252b680dbae9a51343eb2488d057c3c43d2",
"tokens.txt": "ec182b70dd42113aff6c5372c75cac58c952443eb22322f57bbd7f53977d497d"
}
},
{
"id": "silero-vad",
"name": "Silero VAD (v6.2)",
"default": true,
"source": "huggingface",
"repo_id": "streamkit/parakeet-models",
"revision": "main",
"files": [
"silero_vad.onnx"
],
"expected_size_bytes": 2327524,
"license": "MIT",
"license_url": "https://github.com/snakers4/silero-vad/blob/master/LICENSE",
"sha256": "1a153a22f4509e292a94e67d6f9b85e8deb25b4988682b7e174c65279d8788e3"
}
Comment on lines +41 to +55
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Silero VAD model uses top-level sha256 instead of file_checksums

The silero-vad model entry in the parakeet manifest uses a top-level "sha256" field (line 54) rather than the "file_checksums" object used by the parakeet-tdt model (lines 34-39). This is likely because silero-vad has only a single file (silero_vad.onnx), making a per-file checksums object unnecessary. Both formats should be supported by the registry consumer, but this inconsistency within the same manifest is worth noting for schema documentation purposes.

Staging: Open in Devin

Was this helpful? React with 👍 or 👎 to provide feedback.

Debug

Playground

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is from PR #279's base branch, not from changes in this PR. The schema inconsistency (top-level sha256 vs file_checksums) is a pre-existing pattern — worth noting but out of scope here.

]
}
4 changes: 4 additions & 0 deletions dist/registry/plugins/parakeet/0.1.0/manifest.minisig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
untrusted comment: signature from minisign secret key
RUQ/85JEqYXEgb3NHkk8EDvKfvijFiOhUMrmR97Tqb5NEYf3kTZTK+U5IHo10l0lOfInZaLjscG7wQ6OqfgO6gaRAnqlUzMXmgo=
trusted comment: timestamp:1775850398 file:manifest.json hashed
BMn5YTOa/ekLGbyRUiXr5cnwpYr8NrU+bQrKORovVYFIUtYDDwUyzvELqGjs/tShSlT8Ws7UVtBDdSVdJlOxAg==
14 changes: 14 additions & 0 deletions docs/public/registry/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,20 @@
}
]
},
{
"id": "parakeet",
"name": "Parakeet TDT",
"description": "Fast speech-to-text using NVIDIA Parakeet TDT via sherpa-onnx",
"latest": "0.1.0",
"versions": [
{
"version": "0.1.0",
"manifest_url": "https://streamkit.dev/registry/plugins/parakeet/0.1.0/manifest.json",
"signature_url": "https://streamkit.dev/registry/plugins/parakeet/0.1.0/manifest.minisig",
"published_at": "2026-04-10"
}
]
},
{
"id": "piper",
"name": "Piper",
Expand Down
57 changes: 57 additions & 0 deletions docs/public/registry/plugins/parakeet/0.1.0/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"schema_version": 1,
"id": "parakeet",
"name": "Parakeet TDT",
"version": "0.1.0",
"node_kind": "parakeet",
"kind": "native",
"description": "Fast speech-to-text using NVIDIA Parakeet TDT via sherpa-onnx",
"license": "MPL-2.0",
"homepage": "https://huggingface.co/nvidia/parakeet-tdt-0.6b-v2",
"entrypoint": "libparakeet.so",
"bundle": {
"url": "https://github.com/streamer45/streamkit/releases/download/plugin-parakeet-v0.1.0/parakeet-0.1.0-bundle.tar.zst",
"sha256": "9ca3cd97ba3c665517dd1319f8492c15b6b97549231577b640bbbc0f71aa60c3",
"size_bytes": 15635462
},
"models": [
{
"id": "parakeet-tdt-0.6b-v2-int8",
"name": "Parakeet TDT 0.6B v2 (English, INT8)",
"default": true,
"source": "huggingface",
"repo_id": "streamkit/parakeet-models",
"revision": "main",
"files": [
"encoder.int8.onnx",
"decoder.int8.onnx",
"joiner.int8.onnx",
"tokens.txt"
],
"expected_size_bytes": 661190513,
"license": "CC-BY-4.0",
"license_url": "https://huggingface.co/nvidia/parakeet-tdt-0.6b-v2",
"file_checksums": {
"encoder.int8.onnx": "a32b12d17bbbc309d0686fbbcc2987b5e9b8333a7da83fa6b089f0a2acd651ab",
"decoder.int8.onnx": "b6bb64963457237b900e496ee9994b59294526439fbcc1fecf705b31a15c6b4e",
"joiner.int8.onnx": "7946164367946e7f9f29a122407c3252b680dbae9a51343eb2488d057c3c43d2",
"tokens.txt": "ec182b70dd42113aff6c5372c75cac58c952443eb22322f57bbd7f53977d497d"
}
},
{
"id": "silero-vad",
"name": "Silero VAD (v6.2)",
"default": true,
"source": "huggingface",
"repo_id": "streamkit/parakeet-models",
"revision": "main",
"files": [
"silero_vad.onnx"
],
"expected_size_bytes": 2327524,
"license": "MIT",
"license_url": "https://github.com/snakers4/silero-vad/blob/master/LICENSE",
"sha256": "1a153a22f4509e292a94e67d6f9b85e8deb25b4988682b7e174c65279d8788e3"
}
]
}
4 changes: 4 additions & 0 deletions docs/public/registry/plugins/parakeet/0.1.0/manifest.minisig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
untrusted comment: signature from minisign secret key
RUQ/85JEqYXEgb3NHkk8EDvKfvijFiOhUMrmR97Tqb5NEYf3kTZTK+U5IHo10l0lOfInZaLjscG7wQ6OqfgO6gaRAnqlUzMXmgo=
trusted comment: timestamp:1775850398 file:manifest.json hashed
BMn5YTOa/ekLGbyRUiXr5cnwpYr8NrU+bQrKORovVYFIUtYDDwUyzvELqGjs/tShSlT8Ws7UVtBDdSVdJlOxAg==
12 changes: 12 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -1389,6 +1389,18 @@ e2e-external url filter='':
@echo "Running E2E tests against {{url}}..."
@cd e2e && E2E_BASE_URL={{url}} bun run test:only {{ if filter != "" { "--grep '" + filter + "'" } else { "" } }}

# Run headless pipeline validation tests (no browser required).
# Requires a running skit server — pass its URL as an argument.
# Each .yml in samples/pipelines/test/ becomes a test case; a companion
# .toml sidecar declares the expected ffprobe output.
#
# Usage:
# just test-pipelines http://localhost:4545
# just test-pipelines http://localhost:4545 vp9 # filter by name
test-pipelines url filter='':
@echo "Running headless pipeline validation tests against {{url}}..."
@cd tests/pipeline-validation && PIPELINE_TEST_URL={{url}} cargo test --test validate {{ if filter != "" { "-- " + filter } else { "" } }}

# Show E2E test report
[working-directory: 'e2e']
e2e-report:
Expand Down
11 changes: 11 additions & 0 deletions samples/pipelines/test/dav1d_roundtrip/expected.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: © 2025 StreamKit Contributors
#
# SPDX-License-Identifier: MPL-2.0

requires_node = "video::dav1d::decoder"
output_extension = ".webm"
codec_name = "av1"
width = 320
height = 240
container_format = "matroska,webm"
pix_fmt = "yuv420p"
Loading