ruby_raider 4.0.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36caa6e3075d166277f9cafe8073ccd81f9ada8706a3df11ce93a6073b45d130
4
- data.tar.gz: 6aeedcccd3623931f16eb8e082635f93f4946e6870ca79a7de9f03478d868034
3
+ metadata.gz: d516f44eddaa410a882fb64a08755338486c30d9eca4755f97c1716f5b5754ca
4
+ data.tar.gz: de1a0fd5c654301482a09830072991d89793e117092bd23515b44e3e8f428c90
5
5
  SHA512:
6
- metadata.gz: 7581c5bb57fd17624148332100f3e4c963323a02f5bff6dfda8aba500b5b478bfbbcb07741f55eb73909beca99e5a88b769a0af437820507c7b9bd3977038038
7
- data.tar.gz: 353af9eab7da4783e38bff479bab069a35bbed7fcd57936b22eb525c443fc7b76136c5408371424690082f164d3e76334d93f093c2219c4bbe1cb8e56d49ed0a
6
+ metadata.gz: f580ff7a46dd54bc6c792d273045e1041e5bd29dceb302468f909661b4f52fbb837786765e3cb65d701526d7c3ab75aacbfa730ae677a0d8443448a292b667c7
7
+ data.tar.gz: bf9a38d296a6b08ff3f2154e35168d75045431076c65a4a9ea376a4c3a76d928c163d5d5b840dc22ab7444c88e2021a7f66157b2760c84eb40a064a9941b98d6
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env bash
2
+ # Builds the ffmpeg binary that RubyRaider::Ffmpeg downloads for failure videos.
3
+ #
4
+ # .github/ffmpeg/build.sh <darwin-arm64|darwin-x64|linux-x64|windows-x64> [out_dir]
5
+ #
6
+ # LGPL build (no --enable-gpl, no --enable-nonfree) with only what the generated
7
+ # VideoHelper needs: PNG frames listed in a concat file, scaled, encoded with libvpx
8
+ # (VP8, VP9 kept for later) into WebM. Every source is pinned by SHA-256 or commit.
9
+ # Also writes the license notices for what is linked in and, in <out_dir>/sources/, the complete
10
+ # corresponding source (FFmpeg and zlib tarballs, a git archive of the libvpx commit) for the release.
11
+ # Runs on: macOS (arm64 or x86_64 runner), Alpine Linux (fully static, musl) and
12
+ # MSYS2 MINGW64 on Windows (static libgcc/winpthread). Needs bash, make, a C compiler,
13
+ # curl, tar, xz, git, pkg-config, perl and nasm (x86_64 targets only).
14
+ set -euo pipefail
15
+
16
+ FFMPEG_VERSION=7.1.5
17
+ FFMPEG_SHA256=de668509caf9e35e3cd162473441fdb29538c6d96ed080292b3cf9e6fc5d558f
18
+ ZLIB_VERSION=1.3.1
19
+ ZLIB_SHA256=9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23
20
+ LIBVPX_TAG=v1.15.2
21
+ LIBVPX_COMMIT=d168454ecd099805c675d4a98c66f4891373302a
22
+ # Only for its license notice: the Linux binary links musl statically (Alpine 3.20 ships musl 1.2.5).
23
+ MUSL_VERSION=1.2.5
24
+ MUSL_SHA256=a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4
25
+ MACOS_MIN=11.0
26
+
27
+ FFMPEG_URL="https://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.xz"
28
+ ZLIB_URL="https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz"
29
+ LIBVPX_REPO=https://chromium.googlesource.com/webm/libvpx
30
+ MUSL_URL="https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz"
31
+
32
+ target="${1:?usage: build.sh <darwin-arm64|darwin-x64|linux-x64|windows-x64> [out_dir]}"
33
+ here="$(cd "$(dirname "$0")" && pwd)"
34
+ out_dir="$(mkdir -p "${2:-dist}" && cd "${2:-dist}" && pwd)"
35
+ work="${FFMPEG_BUILD_DIR:-$(pwd)/build-ffmpeg-$target}"
36
+ prefix="$work/prefix"
37
+ jobs="$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 4)"
38
+
39
+ cflags=""
40
+ ldflags=""
41
+ exe=""
42
+ ffmpeg_flags=(--enable-pthreads)
43
+ zlib_make=()
44
+ case "$target" in
45
+ darwin-arm64)
46
+ vpx_target=arm64-darwin20-gcc
47
+ arch=arm64
48
+ ;;
49
+ darwin-x64)
50
+ vpx_target=x86_64-darwin20-gcc
51
+ arch=x86_64
52
+ ;;
53
+ linux-x64)
54
+ vpx_target=x86_64-linux-gcc
55
+ ldflags="-static"
56
+ ;;
57
+ windows-x64)
58
+ vpx_target=x86_64-win64-gcc
59
+ ldflags="-static"
60
+ exe=".exe"
61
+ ffmpeg_flags=(--enable-w32threads)
62
+ zlib_make=(-f win32/Makefile.gcc)
63
+ ;;
64
+ *)
65
+ echo "unknown target: $target" >&2
66
+ exit 2
67
+ ;;
68
+ esac
69
+
70
+ if [[ "$target" == darwin-* ]]; then
71
+ if [[ "$(uname -m)" != "$arch" ]]; then
72
+ echo "build $target on a $arch Mac (this one is $(uname -m))" >&2
73
+ exit 2
74
+ fi
75
+ export MACOSX_DEPLOYMENT_TARGET="$MACOS_MIN"
76
+ cflags="-mmacosx-version-min=$MACOS_MIN"
77
+ ldflags="-mmacosx-version-min=$MACOS_MIN"
78
+ fi
79
+
80
+ sha256() {
81
+ if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | cut -d' ' -f1; else shasum -a 256 "$1" | cut -d' ' -f1; fi
82
+ }
83
+
84
+ fetch() { # url sha256 file
85
+ local url="$1" want="$2" file="$work/src/$3"
86
+ if [[ ! -f "$file" ]]; then
87
+ echo "fetching $url"
88
+ curl --proto '=https' --tlsv1.2 -sSfL --retry 5 --retry-all-errors --retry-delay 10 -o "$file" "$url"
89
+ fi
90
+ local got
91
+ got="$(sha256 "$file")"
92
+ if [[ "$got" != "$want" ]]; then
93
+ echo "checksum mismatch for $url: got $got, want $want" >&2
94
+ rm -f "$file"
95
+ exit 1
96
+ fi
97
+ }
98
+
99
+ mkdir -p "$work/src" "$prefix"
100
+ cd "$work/src"
101
+
102
+ fetch "$FFMPEG_URL" "$FFMPEG_SHA256" "ffmpeg-${FFMPEG_VERSION}.tar.xz"
103
+ fetch "$ZLIB_URL" "$ZLIB_SHA256" "zlib-${ZLIB_VERSION}.tar.gz"
104
+ rm -rf "ffmpeg-${FFMPEG_VERSION}" "zlib-${ZLIB_VERSION}" libvpx
105
+ tar -xJf "ffmpeg-${FFMPEG_VERSION}.tar.xz"
106
+ tar -xzf "zlib-${ZLIB_VERSION}.tar.gz"
107
+ git -c advice.detachedHead=false clone -q --depth 1 --branch "$LIBVPX_TAG" "$LIBVPX_REPO" libvpx
108
+ got_commit="$(git -C libvpx rev-parse HEAD)"
109
+ if [[ "$got_commit" != "$LIBVPX_COMMIT" ]]; then
110
+ echo "libvpx $LIBVPX_TAG is $got_commit, want $LIBVPX_COMMIT" >&2
111
+ exit 1
112
+ fi
113
+
114
+ echo "== zlib $ZLIB_VERSION"
115
+ (
116
+ cd "zlib-${ZLIB_VERSION}"
117
+ if [[ "$target" == windows-x64 ]]; then
118
+ make -s "${zlib_make[@]}" -j"$jobs" libz.a CFLAGS="-O2"
119
+ mkdir -p "$prefix/include" "$prefix/lib"
120
+ cp zlib.h zconf.h "$prefix/include/"
121
+ cp libz.a "$prefix/lib/"
122
+ else
123
+ CFLAGS="-O2 -fPIC $cflags" ./configure --static --prefix="$prefix" >/dev/null
124
+ make -s -j"$jobs"
125
+ make -s install >/dev/null
126
+ fi
127
+ )
128
+
129
+ echo "== libvpx $LIBVPX_TAG ($vpx_target)"
130
+ (
131
+ cd libvpx
132
+ ./configure --prefix="$prefix" --target="$vpx_target" \
133
+ --enable-static --disable-shared --enable-pic \
134
+ --enable-vp8 --enable-vp9 --disable-examples --disable-tools --disable-docs \
135
+ --disable-unit-tests --disable-install-bins --disable-install-docs \
136
+ ${cflags:+--extra-cflags="$cflags"} >/dev/null
137
+ make -s -j"$jobs" >/dev/null
138
+ make -s install >/dev/null
139
+ )
140
+
141
+ echo "== ffmpeg $FFMPEG_VERSION"
142
+ configure_args=(
143
+ --prefix="$prefix"
144
+ --pkg-config-flags=--static
145
+ --extra-cflags="-I$prefix/include $cflags"
146
+ --extra-ldflags="-L$prefix/lib $ldflags"
147
+ --disable-everything --disable-autodetect
148
+ --disable-doc --disable-debug --disable-network
149
+ --disable-ffplay --disable-ffprobe --disable-avdevice --disable-swresample
150
+ --enable-static --disable-shared
151
+ "${ffmpeg_flags[@]}"
152
+ --enable-zlib --enable-libvpx
153
+ --enable-protocol=file
154
+ --enable-demuxer=concat,image2,png_pipe
155
+ --enable-decoder=png
156
+ --enable-encoder=libvpx_vp8,libvpx_vp9
157
+ --enable-bsf=vp9_superframe
158
+ --enable-muxer=webm
159
+ --enable-filter=scale,format,null
160
+ )
161
+ (
162
+ cd "ffmpeg-${FFMPEG_VERSION}"
163
+ PKG_CONFIG_PATH="$prefix/lib/pkgconfig" ./configure "${configure_args[@]}" >"$work/configure.log" 2>&1 ||
164
+ { tail -40 ffbuild/config.log; exit 1; }
165
+ make -s -j"$jobs" "ffmpeg$exe" >/dev/null
166
+ cp "ffmpeg$exe" "$out_dir/ffmpeg-7.1-$target$exe"
167
+ grep -q '^CONFIG_GPL=yes' ffbuild/config.mak && { echo 'GPL build: refusing' >&2; exit 1; }
168
+ grep -q '^CONFIG_NONFREE=yes' ffbuild/config.mak && { echo 'nonfree build: refusing' >&2; exit 1; }
169
+ cp COPYING.LGPLv2.1 "$out_dir/"
170
+ )
171
+ cp libvpx/LICENSE "$out_dir/libvpx-LICENSE"
172
+ cp libvpx/PATENTS "$out_dir/libvpx-PATENTS"
173
+ sed -n '/^Copyright notice:/,$p' "zlib-${ZLIB_VERSION}/README" >"$out_dir/zlib-LICENSE"
174
+ case "$target" in
175
+ linux-x64)
176
+ fetch "$MUSL_URL" "$MUSL_SHA256" "musl-${MUSL_VERSION}.tar.gz"
177
+ tar -xzOf "musl-${MUSL_VERSION}.tar.gz" "musl-${MUSL_VERSION}/COPYRIGHT" >"$out_dir/musl-COPYRIGHT"
178
+ ;;
179
+ windows-x64)
180
+ # Static libgcc, mingw-w64 CRT and winpthreads: copy MSYS2's license files for them.
181
+ notices="$out_dir/mingw-w64-notices"
182
+ mkdir -p "$notices"
183
+ for dir in /mingw64/share/licenses/*; do
184
+ case "$(basename "$dir")" in
185
+ *winpthread* | *crt* | *gcc-libs* | *libwinpthread* | *headers*) cp -R "$dir" "$notices/" ;;
186
+ esac
187
+ done
188
+ [[ -n "$(ls -A "$notices")" ]] || { echo 'no mingw-w64 license files found' >&2; exit 1; }
189
+ ;;
190
+ esac
191
+ mkdir -p "$out_dir/sources"
192
+ cp "ffmpeg-${FFMPEG_VERSION}.tar.xz" "zlib-${ZLIB_VERSION}.tar.gz" "$out_dir/sources/"
193
+ git -C libvpx archive --format=tar.gz --prefix="libvpx-${LIBVPX_TAG#v}/" -o "$out_dir/sources/libvpx-${LIBVPX_TAG#v}.tar.gz" HEAD
194
+
195
+ binary="$out_dir/ffmpeg-7.1-$target$exe"
196
+ # arm64 macOS will not run an unsigned binary; re-apply the linker's ad-hoc signature.
197
+ [[ "$target" == darwin-* ]] && codesign --force --sign - "$binary"
198
+
199
+ {
200
+ echo "target: $target"
201
+ echo "ffmpeg: $FFMPEG_VERSION $FFMPEG_URL sha256 $FFMPEG_SHA256"
202
+ echo "zlib: $ZLIB_VERSION $ZLIB_URL sha256 $ZLIB_SHA256"
203
+ echo "libvpx: $LIBVPX_TAG $LIBVPX_REPO commit $LIBVPX_COMMIT"
204
+ echo "configure: ${configure_args[*]}" | sed "s#$prefix#\$PREFIX#g"
205
+ echo "sha256: $(sha256 "$binary") $(basename "$binary")"
206
+ } >"$out_dir/BUILD-$target.txt"
207
+ cat "$out_dir/BUILD-$target.txt"
208
+ "$here/check.sh" "$binary" "$work/check"
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env bash
2
+ # Proves a built ffmpeg does what the generated VideoHelper asks of it:
3
+ # .github/ffmpeg/check.sh <ffmpeg binary> [work_dir]
4
+ # 1. links only (unless SKIP_LINKAGE is set) to libraries every machine of that OS has;
5
+ # 2. runs VideoHelper#ffmpeg_arguments' exact encode on sample PNG frames;
6
+ # 3. encodes the same frames with libvpx-vp9 too (built for later use);
7
+ # 4. if FFPROBE is set (or ffprobe is on PATH), checks both WebMs (probe.sh).
8
+ # Writes <work_dir>/video.webm and <work_dir>/vp9.webm.
9
+ set -euo pipefail
10
+
11
+ binary="$1"
12
+ work="${2:-$(mktemp -d)}"
13
+ here="$(cd "$(dirname "$0")" && pwd)"
14
+ rm -rf "$work" && mkdir -p "$work"
15
+
16
+ echo "== linkage"
17
+ case "${SKIP_LINKAGE:+skip}$(uname -s)" in
18
+ skip*) echo '(skipped)' ;;
19
+ Darwin)
20
+ otool -L "$binary" | tail -n +2 | tee "$work/libs.txt"
21
+ if grep -v -E '^\s*/(usr/lib|System/Library)/' "$work/libs.txt"; then
22
+ echo 'links to a non-system library' >&2
23
+ exit 1
24
+ fi
25
+ codesign --verify --verbose "$binary"
26
+ otool -l "$binary" | grep -A4 -E 'LC_BUILD_VERSION|LC_VERSION_MIN_MACOSX' | grep -E 'minos|version' | head -2
27
+ ;;
28
+ Linux)
29
+ file "$binary"
30
+ file "$binary" | grep -q 'statically linked' || { echo 'not statically linked' >&2; exit 1; }
31
+ ;;
32
+ MINGW* | MSYS* | CYGWIN*)
33
+ objdump -p "$binary" | grep 'DLL Name' | tee "$work/libs.txt"
34
+ # Only Windows system DLLs: no libgcc, libwinpthread, libvpx, zlib.
35
+ if grep -v -i -E 'DLL Name: (KERNEL32|msvcrt|ADVAPI32|USER32|bcrypt|ole32|shell32|api-ms-win-[a-z0-9-]+)\.dll' "$work/libs.txt"; then
36
+ echo 'links to a non-system DLL' >&2
37
+ exit 1
38
+ fi
39
+ ;;
40
+ esac
41
+
42
+ echo "== version"
43
+ "$binary" -hide_banner -version | head -3
44
+ if "$binary" -hide_banner -version | grep -q -- '--enable-gpl\|--enable-nonfree'; then
45
+ echo 'GPL or nonfree build' >&2
46
+ exit 1
47
+ fi
48
+ "$binary" -hide_banner -encoders 2>/dev/null | grep -E 'libvpx' || { echo 'no libvpx encoder' >&2; exit 1; }
49
+
50
+ echo "== encode (VideoHelper#ffmpeg_arguments)"
51
+ ruby "$here/frames.rb" "$work"
52
+ # Relative names in list.txt resolve against the list's directory, as in the helper's tmpdir.
53
+ "$binary" -y -loglevel error -f concat -safe 0 -i "$work/list.txt" \
54
+ -vf "scale='min(1280,iw)':-2" -c:v libvpx -deadline realtime \
55
+ -b:v 1M -r 5 -pix_fmt yuv420p "$work/video.webm"
56
+ size="$(wc -c <"$work/video.webm" | tr -d ' ')"
57
+ echo "video.webm: $size bytes"
58
+ [[ "$size" -gt 1000 ]] || { echo 'video too small' >&2; exit 1; }
59
+
60
+ echo "== encode (VP9)"
61
+ "$binary" -y -loglevel error -f concat -safe 0 -i "$work/list.txt" \
62
+ -vf "scale='min(1280,iw)':-2" -c:v libvpx-vp9 -deadline realtime \
63
+ -b:v 1M -r 5 -pix_fmt yuv420p "$work/vp9.webm"
64
+ [[ "$(wc -c <"$work/vp9.webm" | tr -d ' ')" -gt 1000 ]] || { echo 'vp9 video too small' >&2; exit 1; }
65
+
66
+ probe="${FFPROBE:-$(command -v ffprobe || true)}"
67
+ if [[ -n "$probe" ]]; then
68
+ "$here/probe.sh" "$probe" "$work/video.webm"
69
+ "$here/probe.sh" "$probe" "$work/vp9.webm" vp9
70
+ else
71
+ echo "(no ffprobe here: the validate job probes this video)"
72
+ fi
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Writes sample "screenshots" and the concat list the generated VideoHelper builds:
4
+ # ruby frames.rb <dir> [width] [height] [count]
5
+ # RGBA PNGs with odd dimensions (so scale='min(1280,iw)':-2 has to round), stdlib only.
6
+ require 'zlib'
7
+
8
+ dir, width, height, count = ARGV
9
+ width = (width || 1366).to_i
10
+ height = (height || 657).to_i
11
+ count = (count || 12).to_i
12
+
13
+ def chunk(type, data)
14
+ [data.bytesize].pack('N') + type + data + [Zlib.crc32(type + data)].pack('N')
15
+ end
16
+
17
+ def png(width, height, shift)
18
+ rows = Array.new(height) do |y|
19
+ row = Array.new(width) do |x|
20
+ [(x + shift * 20) % 256, (y + shift * 7) % 256, (x ^ y) % 256, 255].pack('C4')
21
+ end
22
+ "\x00#{row.join}"
23
+ end
24
+ "\x89PNG\r\n\x1A\n".b +
25
+ chunk('IHDR', [width, height, 8, 6, 0, 0, 0].pack('NNCCCCC')) +
26
+ chunk('IDAT', Zlib::Deflate.deflate(rows.join, 1)) +
27
+ chunk('IEND', '')
28
+ end
29
+
30
+ # Same shape as VideoHelper#concat_list: each frame lasts until the next, clamped to [1/fps, 2.0].
31
+ names = Array.new(count) { |i| format('frame-%06d.png', i + 1) }
32
+ names.each_with_index { |name, i| File.binwrite(File.join(dir, name), png(width, height, i)) }
33
+ lines = names.each_with_index.flat_map { |name, i| ["file '#{name}'", format('duration %.3f', i.even? ? 0.2 : 1.1)] }
34
+ File.write(File.join(dir, 'list.txt'), (lines << "file '#{names.last}'").join("\n") << "\n")
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env bash
2
+ # probe.sh <ffprobe> <video.webm> [codec, default vp8]: one video stream of that codec, 1280x616 (1366x657 scaled to an even height),
3
+ # about 8 s long, and the whole file decodes without errors.
4
+ set -euo pipefail
5
+
6
+ probe="$1"
7
+ video="$2"
8
+ codec="${3:-vp8}"
9
+ stream="$("$probe" -v error -select_streams v -show_entries stream=codec_name,width,height,pix_fmt -of csv=p=0 "$video")"
10
+ format="$("$probe" -v error -show_entries format=format_name -of default=nw=1:nk=1 "$video")"
11
+ duration="$("$probe" -v error -show_entries format=duration -of default=nw=1:nk=1 "$video")"
12
+ echo "$(basename "$video"): stream $stream; format $format; duration $duration"
13
+ [[ "$stream" == "$codec,1280,616,yuv420p" ]] || { echo "unexpected stream: $stream" >&2; exit 1; }
14
+ [[ "$format" == "matroska,webm" ]] || { echo "unexpected format: $format" >&2; exit 1; }
15
+ awk -v d="$duration" 'BEGIN { exit !(d > 7 && d < 9) }' || { echo "unexpected duration: $duration" >&2; exit 1; }
16
+ errors="$("${probe%probe}mpeg" -v error -i "$video" -f null - 2>&1 || true)"
17
+ [[ -z "$errors" ]] || { echo "decode errors: $errors" >&2; exit 1; }
@@ -0,0 +1,160 @@
1
+ name: ffmpeg build
2
+
3
+ # Builds the four ffmpeg binaries that RubyRaider::Ffmpeg downloads for failure videos
4
+ # (.github/ffmpeg/build.sh), tests each one on a second runner, and uploads them as
5
+ # workflow artifacts. It never publishes: the ffmpeg-7.1 release is created by hand from
6
+ # the downloaded artifacts of one run, so the release bytes are the bytes MANIFEST pins.
7
+ on:
8
+ workflow_dispatch:
9
+ pull_request:
10
+ paths:
11
+ - .github/ffmpeg/**
12
+ - .github/workflows/ffmpeg.yml
13
+ # check.sh repeats VideoHelper#ffmpeg_arguments: a new filter or codec there needs a rebuild.
14
+ - lib/generators/templates/helpers/video_helper.tt
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ concurrency:
20
+ group: ffmpeg-${{ github.ref }}
21
+ cancel-in-progress: true
22
+
23
+ jobs:
24
+ build:
25
+ name: build ${{ matrix.target }}
26
+ runs-on: ${{ matrix.os }}
27
+ timeout-minutes: 60
28
+ strategy:
29
+ fail-fast: false
30
+ matrix:
31
+ include:
32
+ - { target: darwin-arm64, os: macos-15 }
33
+ - { target: darwin-x64, os: macos-15-intel }
34
+ - { target: linux-x64, os: ubuntu-24.04 }
35
+ - { target: windows-x64, os: windows-2022 }
36
+ steps:
37
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
38
+ with:
39
+ persist-credentials: false
40
+
41
+ - name: Build (macOS)
42
+ if: runner.os == 'macOS'
43
+ run: |
44
+ brew install nasm pkgconf
45
+ .github/ffmpeg/build.sh ${{ matrix.target }} dist
46
+
47
+ # Alpine/musl gives a fully static binary that runs on any x86_64 Linux.
48
+ - name: Build (Linux, Alpine container)
49
+ if: runner.os == 'Linux'
50
+ run: |
51
+ docker run --rm -v "$PWD:/w" -w /w alpine:3.20@sha256:d9e853e87e55526f6b2917df91a2115c36dd7c696a35be12163d44e6e2a4b6bc sh -c '
52
+ apk add --no-cache bash build-base nasm perl pkgconf git curl xz tar diffutils file ruby &&
53
+ .github/ffmpeg/build.sh linux-x64 dist'
54
+
55
+ - uses: msys2/setup-msys2@ec48f7c5447b3140e2b088413ae3a55687bccb6e # v2
56
+ if: runner.os == 'Windows'
57
+ with:
58
+ msystem: MINGW64
59
+ update: false
60
+ install: >-
61
+ make diffutils git tar xz curl perl
62
+ mingw-w64-x86_64-gcc mingw-w64-x86_64-nasm mingw-w64-x86_64-pkgconf mingw-w64-x86_64-ruby
63
+
64
+ - name: Build (Windows, MSYS2 MINGW64)
65
+ if: runner.os == 'Windows'
66
+ shell: msys2 {0}
67
+ run: .github/ffmpeg/build.sh windows-x64 dist
68
+
69
+ - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
70
+ with:
71
+ name: ffmpeg-7.1-${{ matrix.target }}
72
+ path: |
73
+ dist/ffmpeg-7.1-*
74
+ dist/BUILD-*.txt
75
+ dist/COPYING.LGPLv2.1
76
+ dist/libvpx-LICENSE
77
+ dist/libvpx-PATENTS
78
+ dist/zlib-LICENSE
79
+ dist/musl-COPYRIGHT
80
+ dist/mingw-w64-notices/
81
+ if-no-files-found: error
82
+ retention-days: 90
83
+
84
+ # The complete corresponding source, once (every target builds from the same pinned sources).
85
+ - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
86
+ if: matrix.target == 'linux-x64'
87
+ with:
88
+ name: ffmpeg-7.1-sources
89
+ path: dist/sources/
90
+ if-no-files-found: error
91
+ retention-days: 90
92
+
93
+ # Each binary on a fresh runner (another macOS version, older glibc Linux, newer Windows; darwin-x64
94
+ # only has the macos-15-intel label), running VideoHelper's exact encode.
95
+ test:
96
+ name: test ${{ matrix.target }} on ${{ matrix.os }}
97
+ needs: build
98
+ runs-on: ${{ matrix.os }}
99
+ timeout-minutes: 15
100
+ strategy:
101
+ fail-fast: false
102
+ matrix:
103
+ include:
104
+ - { target: darwin-arm64, os: macos-26 }
105
+ - { target: darwin-x64, os: macos-15-intel }
106
+ - { target: linux-x64, os: ubuntu-22.04 }
107
+ - { target: windows-x64, os: windows-2025 }
108
+ defaults:
109
+ run:
110
+ shell: bash
111
+ steps:
112
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
113
+ with:
114
+ persist-credentials: false
115
+ - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
116
+ with:
117
+ name: ffmpeg-7.1-${{ matrix.target }}
118
+ path: dist
119
+ - name: Encode like VideoHelper
120
+ run: |
121
+ bin="dist/ffmpeg-7.1-${{ matrix.target }}"
122
+ [ "${{ runner.os }}" = Windows ] && bin="$bin.exe"
123
+ chmod +x "$bin"
124
+ # Linkage was audited in the build job, where the toolchain's tools are.
125
+ SKIP_LINKAGE=1 .github/ffmpeg/check.sh "$bin" "$RUNNER_TEMP/check"
126
+ mv "$RUNNER_TEMP/check/video.webm" "video-${{ matrix.target }}.webm"
127
+ mv "$RUNNER_TEMP/check/vp9.webm" "vp9-${{ matrix.target }}.webm"
128
+ - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
129
+ with:
130
+ name: video-${{ matrix.target }}
131
+ path: |
132
+ video-${{ matrix.target }}.webm
133
+ vp9-${{ matrix.target }}.webm
134
+ retention-days: 14
135
+
136
+ validate:
137
+ name: validate videos and print checksums
138
+ needs: test
139
+ runs-on: ubuntu-24.04
140
+ steps:
141
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
142
+ with:
143
+ persist-credentials: false
144
+ - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
145
+ with:
146
+ path: artifacts
147
+ pattern: '{ffmpeg-7.1-*,video-*}'
148
+ - name: Probe every video with a reference ffprobe
149
+ run: |
150
+ sudo apt-get update -qq && sudo apt-get install -y -qq ffmpeg >/dev/null
151
+ for video in artifacts/video-*/video-*.webm; do .github/ffmpeg/probe.sh "$(command -v ffprobe)" "$video"; done
152
+ for video in artifacts/video-*/vp9-*.webm; do .github/ffmpeg/probe.sh "$(command -v ffprobe)" "$video" vp9; done
153
+ - name: Checksums for MANIFEST
154
+ run: |
155
+ {
156
+ echo '### ffmpeg-7.1 assets'
157
+ echo '```'
158
+ cd artifacts && sha256sum ffmpeg-7.1-*/ffmpeg-7.1-*
159
+ echo '```'
160
+ } | tee -a "$GITHUB_STEP_SUMMARY"