wai-quantum belongs to another line of work that is shipping releases, and moving it was not needed to put every signature check written in wai-rs on one strict verifier. This undoesc37c3e9aand the quantum-ops part of9b5854aa: wai/wai-sig is gone, wai-rs/src/sig.rs is the rule again (under the `ed25519` feature), and wai-quantum, its Cargo.toml and lock, every other workspace's lock, the quantum-ops corpus and wai_quantum_ops_vectors are as main has them. wai-quantum's lenient checks are reported to its owner instead. The JWP, signer and packaging weak-key cases stay; they verify through wai::sig. The two HTTP falsify patches are cut against wai-rs/src/sig.rs again, and wai-http and wai-pack fire on claim-conformance/_ed25519.py, which their Python verifiers read. Co-Authored-By: Claude Opus 5.5 <[email protected]>
238 lines
11 KiB
YAML
238 lines
11 KiB
YAML
name: wai-pack
|
|
|
|
# The reference packager of WAI's packaging extension (wai/extensions/packaging.md) and
|
|
# its conformance corpus (wai/pack-conformance). Four jobs:
|
|
#
|
|
# - legs: on each architecture of the fleet, clippy with float arithmetic denied (no
|
|
# float decides anything in a package), the tests in release with a floor on how many
|
|
# each target lists, and the corpus recomputed by the crate: the golden packages
|
|
# packed again byte for byte and verified, every mutation's reason.
|
|
# - independent: the corpus recomputed by its second implementation, written in Python
|
|
# from the extension text and sharing no code with wai-pack, the golden packages
|
|
# verified and re-derived from their sources among it.
|
|
# - media: the golden's floor, its CMAF initialization segment and fragments, read and
|
|
# decoded by a media prober (test 14).
|
|
# - licences: every crate in wai-pack's dependency graph is under a licence deny.toml
|
|
# allows; a source-available licence fails it.
|
|
#
|
|
# Push filters match the push's delta, so every path a build or a verifier reads is
|
|
# listed: the crate, the wai crate it builds on, the corpus, the BLAKE3 and integer
|
|
# payload verifiers and the registry export pack_verify.py reads, and this file.
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
on:
|
|
pull_request:
|
|
paths:
|
|
- 'wai/wai-pack/**'
|
|
- 'wai/wai-rs/**'
|
|
- 'wai/pack-conformance/**'
|
|
- 'wai/claim-conformance/_blake3.py'
|
|
- 'wai/claim-conformance/_ed25519.py'
|
|
- 'wai/int-payload-conformance/int_payload_verify.py'
|
|
- 'wai/registry/capabilities.json'
|
|
- '.github/workflows/wai-pack.yml'
|
|
push:
|
|
branches: [main]
|
|
paths:
|
|
- 'wai/wai-pack/**'
|
|
- 'wai/wai-rs/**'
|
|
- 'wai/pack-conformance/**'
|
|
- 'wai/claim-conformance/_blake3.py'
|
|
- 'wai/claim-conformance/_ed25519.py'
|
|
- 'wai/int-payload-conformance/int_payload_verify.py'
|
|
- 'wai/registry/capabilities.json'
|
|
- '.github/workflows/wai-pack.yml'
|
|
|
|
jobs:
|
|
legs:
|
|
name: wai-pack · ${{ matrix.os }}
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
# Self-hosted fleet labels: x86_64 by linux, arm64 by linux-arm64 and macos.
|
|
# A Windows leg waits for its runner (see wai-byte-equality.yml).
|
|
os: [linux, linux-arm64, macos]
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
|
|
# The docker runners ship no Rust, so rustup is bootstrapped; the macOS host has
|
|
# it, but launchd's PATH omits ~/.cargo/bin.
|
|
- name: Install Rust 1.98.0
|
|
shell: bash
|
|
run: |
|
|
export PATH="$HOME/.cargo/bin:$PATH"
|
|
command -v rustup >/dev/null 2>&1 || \
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.98.0
|
|
rustup toolchain install 1.98.0 --profile minimal
|
|
rustup default 1.98.0
|
|
rustup component add --toolchain 1.98.0 clippy
|
|
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
|
|
|
# clippy::float_arithmetic is denied for the library and the CLI (Cargo.toml and
|
|
# the crate attributes); -D warnings makes every other lint fail the step too.
|
|
- name: clippy, float arithmetic denied
|
|
working-directory: wai/wai-pack
|
|
run: cargo clippy --locked --all-targets -- -D warnings
|
|
|
|
- name: Tests (release)
|
|
working-directory: wai/wai-pack
|
|
run: cargo test --release --locked
|
|
|
|
# A target that lost its tests (a module dropped, a cfg that compiles them out)
|
|
# would still report ok. Each target must list at least as many tests as it had
|
|
# when the floor was set; raise a floor when tests are added.
|
|
- name: Test-count floor per target
|
|
shell: bash
|
|
working-directory: wai/wai-pack
|
|
run: |
|
|
set -euo pipefail
|
|
fail=0
|
|
while read -r target floor; do
|
|
n=$(cargo test --release --locked $target -- --list 2>/dev/null | grep -c ': test$' || true)
|
|
echo "$target: $n tests (floor $floor)"
|
|
[ "$n" -ge "$floor" ] || { echo "::error::$target lists $n tests, under its floor of $floor"; fail=1; }
|
|
done <<'EOF'
|
|
--lib 28
|
|
--test=conformance 1
|
|
--test=packs 7
|
|
--test=review 9
|
|
--test=refusals 5
|
|
--test=scenecut 3
|
|
--test=source_alloc 1
|
|
EOF
|
|
exit $fail
|
|
|
|
- name: The corpus, recomputed by wai-pack
|
|
working-directory: wai/wai-pack
|
|
run: cargo run --release --locked --bin wai-pack -- conformance check ../pack-conformance
|
|
|
|
independent:
|
|
name: wai-pack · independent verifier (Python)
|
|
runs-on: linux
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.11'
|
|
# The standard library (tomllib, hashlib); BLAKE3 from the shared pure-Python module
|
|
# beside the claim corpus; the package receipts' Ed25519 equation from the
|
|
# `cryptography` package, pinned with its dependencies by SHA-256 so pip installs only
|
|
# the files the requirements name.
|
|
- name: Install the Ed25519 library (hashes required)
|
|
shell: bash
|
|
working-directory: wai
|
|
run: python -m pip install --require-hashes -r pack-conformance/requirements-verify.txt
|
|
- name: pack_verify.py
|
|
working-directory: wai
|
|
shell: bash
|
|
run: python3 pack-conformance/pack_verify.py pack-conformance
|
|
- name: Install Rust 1.98.0
|
|
shell: bash
|
|
run: |
|
|
export PATH="$HOME/.cargo/bin:$PATH"
|
|
command -v rustup >/dev/null 2>&1 || \
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.98.0
|
|
rustup toolchain install 1.98.0 --profile minimal
|
|
rustup default 1.98.0
|
|
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
|
# The source readers differentially: seeded Y4M and WAV mutations, every verdict of
|
|
# wai-pack (debug and release, both with overflow checks) equal to pack_verify.py's,
|
|
# and no reader panicking.
|
|
- name: source_diff.py, wai-pack against pack_verify.py
|
|
shell: bash
|
|
working-directory: wai/wai-pack
|
|
run: |
|
|
set -euo pipefail
|
|
cargo build --locked --bin wai-pack
|
|
cargo build --release --locked --bin wai-pack
|
|
for profile in debug release; do
|
|
python3 ../pack-conformance/source_diff.py "target/$profile/wai-pack" 1 3000
|
|
done
|
|
# The policy reader differentially: byte-level cases and seeded random policies,
|
|
# every verdict and digest of wai-pack equal to pack_verify.py's.
|
|
- name: policy_diff.py, wai-pack against pack_verify.py
|
|
shell: bash
|
|
working-directory: wai/wai-pack
|
|
run: python3 ../pack-conformance/policy_diff.py target/release/wai-pack 1 3000
|
|
# wai.pack.scenecut/1 differentially: the streaming segmenter against
|
|
# pack_verify.py's on-demand form on seeded random clips.
|
|
- name: segment_diff.py, wai-pack against pack_verify.py
|
|
shell: bash
|
|
working-directory: wai/wai-pack
|
|
run: python3 ../pack-conformance/segment_diff.py target/release/wai-pack 1 2000
|
|
|
|
media:
|
|
name: wai-pack · the floor through a media prober
|
|
runs-on: linux
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- name: Install a media prober
|
|
shell: bash
|
|
run: |
|
|
SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo"
|
|
$SUDO apt-get update -qq
|
|
$SUDO apt-get install -y -qq ffmpeg
|
|
# Test 14: the golden's init.mp4 and its fragments, in its floor playlist's order,
|
|
# read as one AV1 track of every frame of the source, with a key frame at each piece
|
|
# start of the plan and nowhere else, and decode without an error.
|
|
- name: The golden's floor reads and decodes
|
|
shell: bash
|
|
working-directory: wai/pack-conformance/packs/video-base-01/package
|
|
run: |
|
|
set -euo pipefail
|
|
tmp=$(mktemp -d)
|
|
cat floor/v/init.mp4 $(grep -v '^#' hls/classic/floor-v.m3u8 | sed 's#^\.\./\.\./##') > "$tmp/floor.mp4"
|
|
ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=codec_name,width,height,nb_read_frames -of default=nw=1 "$tmp/floor.mp4" | tee "$tmp/probe.txt"
|
|
grep -qx 'codec_name=av1' "$tmp/probe.txt"
|
|
grep -qx 'nb_read_frames=200' "$tmp/probe.txt"
|
|
keys=$(ffprobe -v error -select_streams v:0 -show_entries packet=pts,flags -of csv=p=0 "$tmp/floor.mp4" | awk -F, '$2 ~ /K/ {print $1}' | tr '\n' ' ')
|
|
want=$(tr '\n' ' ' < plan-v.txt)
|
|
echo "key frames: $keys"
|
|
[ "$keys" = "$want" ] || { echo "::error::key frames at $keys; the plan says $want"; exit 1; }
|
|
ffmpeg -v error -xerror -i "$tmp/floor.mp4" -f null -
|
|
echo "the floor reads as one AV1 track of 200 frames, a key frame at each piece start"
|
|
|
|
licences:
|
|
name: wai-pack · dependency licences
|
|
runs-on: linux
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- name: Install Rust 1.98.0
|
|
shell: bash
|
|
run: |
|
|
export PATH="$HOME/.cargo/bin:$PATH"
|
|
command -v rustup >/dev/null 2>&1 || \
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.98.0
|
|
rustup toolchain install 1.98.0 --profile minimal
|
|
rustup default 1.98.0
|
|
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
|
- name: Install cargo-deny
|
|
shell: bash
|
|
run: cargo install --locked cargo-deny --version 0.19.8
|
|
- name: cargo deny check licenses
|
|
working-directory: wai/wai-pack
|
|
run: cargo deny --locked check licenses
|
|
# deny.toml's MPL-2.0 exception covers cbindgen as wai's build-time tool: it must
|
|
# reach wai-pack through no normal (linked) edge. The second query sees the build
|
|
# edge, so an empty answer from the first is an answer.
|
|
- name: cbindgen is a build dependency only
|
|
shell: bash
|
|
working-directory: wai/wai-pack
|
|
run: |
|
|
set -euo pipefail
|
|
err=$(mktemp)
|
|
if ! linked=$(cargo tree --locked -e normal --target all -i cbindgen 2>"$err"); then
|
|
grep -q "did not match any packages" "$err" || { cat "$err"; exit 1; }
|
|
linked=""
|
|
fi
|
|
if [ -n "$linked" ]; then
|
|
echo "::error::cbindgen is a linked dependency of wai-pack; its MPL-2.0 exception covers a build tool only"
|
|
echo "$linked"
|
|
exit 1
|
|
fi
|
|
cargo tree --locked -e normal,build --target all -i cbindgen | grep -q '^cbindgen v' || { echo "::error::cbindgen not found as wai's build dependency"; exit 1; }
|
|
echo "cbindgen is a build dependency only"
|