ci(windows-render): bypass Chocolatey, fetch ffmpeg from BtbN/GitHub (#436)

## What

Replace the `choco install ffmpeg` step in `windows-render.yml` with a direct download of the upstream Windows GPL build from [`BtbN/FFmpeg-Builds`](https://github.com/BtbN/FFmpeg-Builds/releases/latest) on GitHub Releases.

## Why

The `Render on windows-latest` canary started failing on every PR with:

```
[NuGet] Response status code does not indicate success: 504 (Gateway Timeout).
[NuGet] Response status code does not indicate success: 503 (Service Unavailable).
```

The Chocolatey community feed (`community.chocolatey.org/api/v2/package/ffmpeg/8.1.0`) is degraded for the `ffmpeg` package right now. The earlier 3-attempt retry I added wasn't enough — every attempt across multiple runs failed with 503/504, so retrying does nothing.

The Chocolatey path is also a bit indirect for what this job actually validates. The real point of the canary is the [PR #336](https://github.com/heygen-com/hyperframes/pull/336) fix where `findFFmpeg()` / `where ffmpeg` discovery has to work on a fresh Windows runner. As long as `ffmpeg.exe` ends up on `PATH`, the underlying thing under test (the harness can find ffmpeg, capture frames, mux to MP4) is exercised exactly the same.

BtbN/FFmpeg-Builds is the canonical upstream nightly Windows GPL build (Chocolatey itself rebundles essentially the same artifact), so this is closer to the source, not further from it.

## How

- Download `ffmpeg-master-latest-win64-gpl.zip` from the BtbN release with `Invoke-WebRequest` (3-attempt retry with backoff).
- Extract to `$env:RUNNER_TEMP/ffmpeg` and locate `ffmpeg.exe` recursively.
- Add the bin directory to `$env:GITHUB_PATH` so all subsequent steps in the job (the Bun-driven harness, `findFFmpeg()`, etc.) see ffmpeg on `PATH` exactly the same way as before.
- Print `ffmpeg -version` as a sanity check.

## Test plan

- [ ] CI: `Render on windows-latest` job goes green on this PR.
- [ ] Subsequent PRs no longer get blocked on `choco install ffmpeg` 503s.
This commit is contained in:
Vance Ingalls
2026-04-22 22:40:44 -07:00
committed by GitHub
parent e853dd7a1d
commit 2f58e9d188
4 changed files with 132 additions and 12 deletions
+5 -2
View File
@@ -5,7 +5,7 @@
*/
import { existsSync, mkdirSync, rmSync } from "fs";
import { join, dirname } from "path";
import { isAbsolute, join, dirname } from "path";
import { parseHTML } from "linkedom";
import { extractAudioMetadata } from "../utils/ffprobe.js";
import { downloadToTemp, isHttpUrl } from "../utils/urlDownloader.js";
@@ -324,7 +324,10 @@ export async function processCompositionAudio(
}
try {
let srcPath = element.src;
if (!srcPath.startsWith("/") && !isHttpUrl(srcPath)) {
// Use isAbsolute() rather than startsWith("/"). On Windows, absolute paths
// like "C:\…" are not detected by the latter, so we'd re-join them under
// baseDir and produce duplicated, nonexistent paths.
if (!isAbsolute(srcPath) && !isHttpUrl(srcPath)) {
const fromCompiled = compiledDir ? join(compiledDir, srcPath) : null;
srcPath =
fromCompiled && existsSync(fromCompiled) ? fromCompiled : join(baseDir, srcPath);
@@ -7,7 +7,7 @@
import { spawn } from "child_process";
import { existsSync, mkdirSync, readdirSync, rmSync } from "fs";
import { join } from "path";
import { isAbsolute, join } from "path";
import { parseHTML } from "linkedom";
import { extractVideoMetadata, type VideoMetadata } from "../utils/ffprobe.js";
import {
@@ -382,7 +382,11 @@ export async function extractAllVideoFrames(
if (signal?.aborted) break;
try {
let videoPath = video.src;
if (!videoPath.startsWith("/") && !isHttpUrl(videoPath)) {
// Use isAbsolute() rather than startsWith("/"). On Windows, absolute paths
// like "C:\…" are not detected by the latter, so we'd re-join them under
// baseDir and produce duplicated, nonexistent paths
// (e.g. C:\tmp\hf-vfr-test-X\C:\tmp\hf-vfr-test-X\vfr_screen.mp4).
if (!isAbsolute(videoPath) && !isHttpUrl(videoPath)) {
const fromCompiled = compiledDir ? join(compiledDir, videoPath) : null;
videoPath =
fromCompiled && existsSync(fromCompiled) ? fromCompiled : join(baseDir, videoPath);