Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
41 changes: 40 additions & 1 deletion .github/actions/ci-fixtures/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ runs:
support=$(python3 -I -B -c 'import sys; sys.path.insert(0, "scripts"); from test_oracle import SUPPORT; print(" ".join("scripts/" + name for name in SUPPORT))')
identity="$(cat scripts/gen-fixtures.sh scripts/install-oracle-ffmpeg.sh scripts/oracle-ffmpeg.env $helpers $support | sha256sum | cut -c1-32)"
composed="$(cat docs/design/composed-opus-aac-v2.json scripts/composed_audio.py scripts/composed_audio_fixtures.py scripts/install-oracle-ffmpeg.sh $support | sha256sum | cut -c1-32)"
comparator="$(python3 -I -c 'import json; print(json.load(open("docs/design/composed-opus-aac-v2.json"))["opus_compare"]["sha256"])')"
echo "key=linux-x64-fixtures-$identity" >> "$GITHUB_OUTPUT"
echo "composed=linux-x64-composed-$composed" >> "$GITHUB_OUTPUT"
echo "comparator=comparator-archive-$comparator" >> "$GITHUB_OUTPUT"
- name: Restore the fixtures
id: fixtures
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
Expand All @@ -26,6 +28,12 @@ runs:
with:
path: ${{ runner.temp }}/coreav-composed-fixtures
key: ${{ steps.key.outputs.composed }}
- name: Cache the pinned comparator archive
if: steps.composed.outputs.cache-hit != 'true'
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ${{ runner.temp }}/coreav-comparator-archive
key: ${{ steps.key.outputs.comparator }}
- name: Cache pinned black-box binaries
if: steps.fixtures.outputs.cache-hit != 'true' || steps.composed.outputs.cache-hit != 'true'
id: ffmpeg-cache
Expand All @@ -48,14 +56,45 @@ runs:
python3 -I scripts/oracle_pin.py --verify-bin "$RUNNER_TEMP/coreav-oracle-bin"
export PATH="$RUNNER_TEMP/coreav-oracle-bin:$PATH"
scripts/gen-fixtures.sh "$RUNNER_TEMP/coreav-fixtures"
- name: Fetch the pinned comparator archive on a cache miss
if: steps.composed.outputs.cache-hit != 'true'
shell: bash
run: |
set -euo pipefail
read -r url digest < <(python3 -I -c 'import json; pin = json.load(open("docs/design/composed-opus-aac-v2.json"))["opus_compare"]; print(pin["url"], pin["sha256"])')
archive="$RUNNER_TEMP/coreav-comparator-archive/opus.tar.gz"
if [ -f "$archive" ] && ! echo "$digest $archive" | sha256sum --check --status -; then
echo "::warning::the cached comparator archive has another digest; fetching it again"
rm -f "$archive"
fi
if [ ! -f "$archive" ]; then
download="$RUNNER_TEMP/comparator-archive.download"
status=0
curl --fail --silent --show-error --location --proto =https --proto-redir =https --connect-timeout 15 \
--max-time 120 --max-filesize 10485760 --retry 3 --retry-all-errors --retry-delay 5 \
--output "$download" "$url" || status=$?
if [ "$status" -ne 0 ] || ! echo "$digest $download" | sha256sum --check --status -; then
echo "::warning::comparator archive fetch failed (curl exit $status); the generator downloads it itself"
rm -f "$download"
else
mkdir -p "${archive%/*}"
mv "$download" "$archive"
fi
fi
if [ -f "$archive" ]; then
mkdir -p "$RUNNER_TEMP/coreav-comparator-curl"
cp .github/actions/ci-fixtures/comparator-curl.sh "$RUNNER_TEMP/coreav-comparator-curl/curl"
chmod +x "$RUNNER_TEMP/coreav-comparator-curl/curl"
fi
- name: Generate the registered composed-audio fixtures
if: steps.composed.outputs.cache-hit != 'true'
shell: bash
run: |
url=$(python3 -I -c 'import json; print(json.load(open("docs/design/composed-opus-aac-v2.json"))["opus_compare"]["url"])')
export COREAV_COMPARATOR_URL="$url" COREAV_COMPARATOR_ARCHIVE="$RUNNER_TEMP/coreav-comparator-archive/opus.tar.gz"
rm -rf "$RUNNER_TEMP/coreav-composed-fixtures"
for attempt in 1 2 3; do
if python3 -I scripts/composed_audio_fixtures.py \
if env PATH="$RUNNER_TEMP/coreav-comparator-curl:$PATH" python3 -I scripts/composed_audio_fixtures.py \
--ffmpeg "$RUNNER_TEMP/coreav-oracle-bin/ffmpeg" --out "$RUNNER_TEMP/coreav-composed-fixtures"; then
exit 0
fi
Expand Down
19 changes: 19 additions & 0 deletions .github/actions/ci-fixtures/comparator-curl.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
# Stands in for curl while scripts/composed_audio_fixtures.py builds the
# comparator: the request for the registered comparator archive is answered
# from the Actions cache, and the generator's own digest check still judges
# the bytes. Every other request is refused, so a changed address fails at
# once instead of reaching the network unnoticed.
set -euo pipefail
target=
while [ "$#" -gt 1 ]; do
case "$1" in
-o|--output) target="$2"; shift ;;
esac
shift
done
if [ "$#" -ne 1 ] || [ "$1" != "$COREAV_COMPARATOR_URL" ] || [ -z "$target" ]; then
echo 'comparator stand-in for curl: only the registered comparator archive is served' >&2
exit 2
fi
cp "$COREAV_COMPARATOR_ARCHIVE" "$target"
24 changes: 19 additions & 5 deletions .github/workflows/audio-conformance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@ jobs:
OPUS_VECTORS_URL: https://www.ietf.org/proceedings/98/slides/materials-98-codec-opus-newvectors-00.tar.gz
OPUS_VECTORS_SHA256: 6b26a22f9ba87b2b836906a9bb7afec5f8e54d49553b1200382520ee6fedfa55
# opus_compare from libopus 1.6.1. Built and run as a black box: its
# source is compiled, never read, and deleted.
# source is compiled, never read, and deleted. The archive is cached by
# this digest, under the key the ci-fixtures action uses for the same file.
LIBOPUS_URL: https://downloads.xiph.org/releases/opus/opus-1.6.1.tar.gz
LIBOPUS_SHA256: 6ffcb593207be92584df15b32466ed64bbec99109f007c82205f0194572411a1
steps:
Expand Down Expand Up @@ -534,16 +535,29 @@ jobs:
echo "$OPUS_VECTORS_SHA256 vectors.tar.gz" | sha256sum -c -
tar xzf vectors.tar.gz
rm vectors.tar.gz
- name: Cache the pinned comparator archive
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ${{ runner.temp }}/coreav-comparator-archive
key: comparator-archive-${{ env.LIBOPUS_SHA256 }}
- name: Build opus_compare
run: |
set -euo pipefail
archive="$RUNNER_TEMP/coreav-comparator-archive/opus.tar.gz"
if [ -f "$archive" ] && ! echo "$LIBOPUS_SHA256 $archive" | sha256sum --check --status -; then
rm -f "$archive"
fi
if [ ! -f "$archive" ]; then
curl -sSfL --retry 3 --retry-all-errors --retry-delay 5 -o "$RUNNER_TEMP/libopus.tar.gz" "$LIBOPUS_URL"
echo "$LIBOPUS_SHA256 $RUNNER_TEMP/libopus.tar.gz" | sha256sum -c -
mkdir -p "${archive%/*}"
mv "$RUNNER_TEMP/libopus.tar.gz" "$archive"
fi
mkdir -p "$RUNNER_TEMP/opus-compare"
cd "$RUNNER_TEMP/opus-compare"
curl -sSfL --retry 3 --retry-all-errors --retry-delay 5 -o libopus.tar.gz "$LIBOPUS_URL"
echo "$LIBOPUS_SHA256 libopus.tar.gz" | sha256sum -c -
tar xzf libopus.tar.gz opus-1.6.1/src/opus_compare.c
tar xzf "$archive" opus-1.6.1/src/opus_compare.c
cc -O2 -o opus_compare opus-1.6.1/src/opus_compare.c -lm
rm -rf libopus.tar.gz opus-1.6.1
rm -rf opus-1.6.1
- name: The generated tables are what scripts/opus_tables.py makes from the RFC's code
run: python3 -I scripts/opus_tables.py --check --cache "$RUNNER_TEMP/pinned-sources"
- name: Read every packet and decode the twelve vectors (durations against the reference outputs, range state of every packet, opus_compare above 90)
Expand Down
1 change: 1 addition & 0 deletions docs/agents/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ Workflow required checks, path filters, DCO, pinned actions, merge-group reuse,
| Design notes change in the same pull request as the design | test_videotoolbox_owner_docs_do_not_describe_it_as_unimplemented rejects former preimplementation wording for the implemented VideoToolbox owner and requires the plan's explicit CoreAV-to-FFmpeg payload ratio and inclusive bounds (deny.yml). Other design consistency is not enforced: judgment. Rust types cannot establish the meaning of external prose |
| A change of an oracle platform's pin or installer starts every workflow that runs that installer | `scripts/workflow_check.py` (`deny.yml`) checks the platform-specific input lists, including the macOS verifier and its frozen Linux imports. `test_macos_installers_track_only_their_own_required_inputs` checks each macOS input and nested shell calls. A job-level filter (`changed-paths`) is review judgment |
| Fixture cache identities and fixture-consuming workflow triggers include every shared qualification support input, not only the directly called script | The existing `test_oracle.SUPPORT` owner supplies both cache keys; `test_both_fixture_cache_keys_bind_every_owner_support_file` executes both key blocks, changes every support file and rejects missing inputs. `test_all_fixture_support_changes_start_both_wasm_events` and `test_release_and_avi_triggers_cover_qualification_and_fixture_inputs` check the WASM, release and AVI filters against that owner and the generators they run. Workflow path filters cannot consume a Python owner at parse time, so checks prevent drift |
| The pinned comparator archive comes from an Actions cache keyed by its registered digest on every branch, only digest-verified bytes enter that cache, and the generator's own digest check still judges what it is served | `test_comparator_archive_is_cached_by_its_registered_digest_on_every_branch` checks both cache steps' key and path against the registration and that neither save is limited to main; `test_fetch_keeps_only_a_digest_verified_archive_and_installs_the_stand_in_beside_it`, `test_stand_in_serves_only_the_generators_request_for_the_registered_archive` and `test_audio_conformance_builds_the_comparator_from_the_cached_archive` execute the shell blocks and the stand-in with a stand-in curl (`deny.yml`). A YAML type cannot govern what a cache step saves |
10 changes: 10 additions & 0 deletions docs/design/ci-checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,16 @@ key is one entry per job id, toolchain and `Cargo.lock`.
script itself, so a new helper joins the key without an edit here) and
`scripts/install-oracle-ffmpeg.sh`. A pull request that changes one of
them generates the fixtures on every push.
- **The comparator archive is cached by its digest on every branch**
(`comparator-archive-<sha256>`, the digest the composed-audio
registration pins). `ci-changes` restores it before generating the
composed-audio fixtures and answers the generator's download of the
registered address from it; the `opus` job of `audio-conformance.yml`
restores the same entry before compiling `opus_compare`. Only an archive
whose digest matched enters the entry, and the generator checks the
digest again on what it is served. A pull request that changes the
composed sources no longer downloads the archive from its publisher on
every push.
- **The Matroska and transport stream oracles restore `isobmff-fixtures`'
cache** (`shared-key: isobmff-fixtures`, `save-if: false`). That job
builds every crate, profile and feature the other two build, so their
Expand Down
Loading
Loading