Skip to content

fix: resolve latest BtbN ffmpeg asset dynamically (#459) - #632

Open
petems wants to merge 3 commits into
charmbracelet:mainfrom
petems:fix/ffmpeg-asset-matcher
Open

fix: resolve latest BtbN ffmpeg asset dynamically (#459)#632
petems wants to merge 3 commits into
charmbracelet:mainfrom
petems:fix/ffmpeg-asset-matcher

Conversation

@petems

@petems petems commented May 11, 2026

Copy link
Copy Markdown

Summary

  • installLatestFfmpeg() looked up release assets from BtbN/FFmpeg-Builds whose names start with ffmpeg-n5.1 and contain linux64-gpl-5.1 / win64-gpl-5.1. That series is no longer published; the latest release only ships n7.1, n8.1, and master-latest variants. As a result every action run errored with Failed to install ffmpeg (Error: Failed to install ffmpeg #459).
  • Replace the hardcoded matcher with a regex that captures the major/minor of any numbered build and picks the highest version in the release. Fall back to the always-present ffmpeg-master-latest-* asset if no numbered build matches, so future BtbN naming bumps don't break the action again.
  • Applied to both linux and win32 branches; darwin uses evermeet.cx and is unaffected.
  • dist/index.js regenerated via npm run package.

Test plan

  • npm run build, npm run format-check, npm run package, npm test all succeed locally.
  • Verified via nektos/act against .github/workflows/ci.yml (ubuntu-latest leg) that the action now installs ffmpeg + ttyd + VHS successfully and vhs -h runs (terminal upload-artifact@v7 failure was an act-image quirk, not an action failure).
  • Upstream CI exercises the macOS and Windows matrix legs that I couldn't run locally.

Fixes #459

* Replace hardcoded `ffmpeg-n5.1` matcher with a regex that captures
  major/minor of any numbered build, then pick the highest version
  present in the release. BtbN/FFmpeg-Builds no longer ships 5.1
  builds, which broke `installLatestFfmpeg()` on every run.
* Fall back to `ffmpeg-master-latest-*` when no numbered build matches
  so future BtbN naming bumps don't break the action again.
* Apply to both linux and win32 branches; darwin uses evermeet.cx and
  is unaffected.

Fixes charmbracelet#459
Comment thread src/dependencies.ts Outdated
Comment thread src/dependencies.ts Outdated
* Use @octokit/openapi-types release-asset type instead of declaring
  a local BtbnAsset interface, per @dougmaitelli's suggestion. The
  octokit type is already available transitively and matches the
  shape returned by repos.getLatestRelease exactly.
* Rename pickBtbnAsset to pickLatestVersionedAsset since the logic
  is generic (highest major.minor with master-name fallback) and is
  not BtbN-specific.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@petems

petems commented May 12, 2026

Copy link
Copy Markdown
Author

Just realised one of my original intentions was to add in more error logging, as one of the original issues is that it just failed without giving details of not being able to find the url, so let me add that in as well

* Add describeMissingAsset helper that builds a descriptive error
  listing the patterns tried and the asset names actually present in
  the release, plus a pointer to file an issue. This addresses the
  silent "Failed to install ffmpeg" failure mode that motivated this
  PR: when upstream renamed BtbN artifacts, users got no context for
  why the download dropped out.
* Throw the descriptive error from both BtbN call sites (linux,
  win32) and from both installTtyd call sites (linux, win32).
* Log the resolved release tag and selected asset URL via core.info
  so successful runs also show what was picked.
* Replace the non-null assertion on the evermeet.cx response with
  explicit status-code and shape checks. @actions/http-client does
  not throw on non-2xx, so the previous code would crash with an
  uninformative TypeError when evermeet was unreachable or changed
  its schema.
* Wrap downloadTool and extract with try/catch that adds the source
  URL and archive path to any underlying error.
* Drop the unreachable trailing reject and the now-redundant
  if (url) wrapper.
@petems
petems force-pushed the fix/ffmpeg-asset-matcher branch from 7eaea1b to 760919c Compare May 12, 2026 12:44
Comment thread src/dependencies.ts
asset =>
asset.name.endsWith('win10.exe') || asset.name.endsWith('win32.exe')
)?.browser_download_url
if (!url) {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This and all the other error throwing might be a bit OOT, but I think it's better to be more explict than less, but happy to scale this back or remove it if it's not your vibe

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think the amount of logs is good, I just wonder if we could make it less repetitive, like, instead of having the check / promise.reject for each case (os / arch) we could probably check after the switch and reject the promise in just one place

Comment thread src/dependencies.ts
break
}
case 'linux': {
url = release.data.assets.find(asset =>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I wonder if it makes sense to use the new pickLatestVersionedAsset for determining the right asset here too

Comment thread src/dependencies.ts
}
switch (osPlatform) {
case 'win32': {
url = release.data.assets.find(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I wonder if it makes sense to use the new pickLatestVersionedAsset for determining the right asset here too

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Not really needed, just a maybe / suggestion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error: Failed to install ffmpeg

2 participants