Files
david 757c540224 build: expose mpv version from reusable build workflows to release
A reusable workflow only exposes top-level workflow_call outputs to the
caller; job outputs are not visible. release.yml read the version from the
build jobs' outputs, which is empty when called via workflow_call, so the
publish job failed with 'mpv version not set' and the v0.41.0 release was
never published.

Each build-* workflow now exposes the version as a workflow_call output,
and release.yml reads it from needs.<job>.outputs.version instead of the
nested needs.<job>.<inner>.outputs.version path.
2026-10-06 13:47:09 +02:00

158 lines
5.9 KiB
YAML

name: build-linux
# Builds a single self-contained libmpv.so for Linux (x86_64) from mpv source
# pinned to a release tag. Every video dependency is built static and linked
# into the one .so; glibc/pthread/dl/m, the system zlib and the system audio
# stack (PipeWire / PulseAudio / ALSA) stay external, mirroring CoreAudio
# (macOS) and WASAPI (Windows), so the OS audio is left dynamic and
# everything else is self contained.
#
# Linux is the easiest of the three platforms: a single native build on an
# ubuntu runner, no cross-compile, no lipo. The only Linux-specific work is the
# font stack: libass (a hard mpv dependency) needs fontconfig (-> expat) where
# macOS/Windows use CoreText/DirectWrite.
#
# Pinned to the mpv tag in ci/versions.env - the version whose client API
# (131077) the jlibmpv JNA bindings are validated against. Bump MPV_REF (and
# the dependency pins) there for a libmpv update. The build recipe
# (dependency versions, static flags) lives in ci/build-libmpv-linux.sh.
#
# Triggers: pull requests (all three build workflows act as the PR check),
# manual workflow_dispatch, and workflow_call from release.yml on tag push.
# A push to main builds nothing on its own.
on:
pull_request:
workflow_dispatch:
workflow_call:
# A called (reusable) workflow only exposes top-level `workflow_call`
# outputs to the caller - job outputs are not. release.yml needs the
# mpv version to name the release assets, so expose it here.
outputs:
version:
description: mpv version the built artifact was compiled from
value: ${{ jobs.linux.outputs.version }}
env:
TARGET: x86_64-linux
jobs:
linux:
runs-on: ubuntu-24.04
outputs:
artifact-name: ${{ steps.artifact.outputs.name }}
version: ${{ steps.artifact.outputs.version }}
env:
CCACHE_BASEDIR: ${{ github.workspace }}
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_MAXSIZE: 500M
steps:
- name: Check out mpv-natives (build scripts)
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Load pinned versions
id: versions
run: |
source ci/versions.env
echo "mpv_ref=$MPV_REF" >> "$GITHUB_OUTPUT"
- name: Check out mpv (pinned tag)
uses: actions/checkout@v4
with:
repository: mpv-player/mpv
ref: ${{ steps.versions.outputs.mpv_ref }}
path: mpv
fetch-depth: 1
- name: Get time
id: get_time
run: echo "timestamp=$(date +%s%N)" >> $GITHUB_OUTPUT
- name: Restore ccache
uses: actions/cache/restore@v4
with:
path: ${{ env.CCACHE_DIR }}
key: ${{ env.TARGET }}-${{ steps.get_time.outputs.timestamp }}
restore-keys: ${{ env.TARGET }}-
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends -y \
ccache nasm ninja-build pkgconf cmake \
libasound2-dev libpulse-dev libpipewire-0.3-dev
python3 -m pip install meson
# Run the vendored build script from inside the mpv source tree, so the
# native build writes linux_prefix/ and the meson build next to mpv's
# meson.build and produces the self-contained .so in mpv/artifact/.
- name: Build self-contained libmpv
working-directory: mpv
run: bash "${{ github.workspace }}/ci/build-libmpv-linux.sh"
- name: Print meson log on failure
if: failure()
run: cat mpv/linux_build/meson-logs/meson-log.txt
- name: Collect artifact
run: |
mkdir -p artifact-libmpv
cp -pv mpv/artifact/libmpv.so artifact-libmpv/
echo "=== contents ==="
ls -l artifact-libmpv
# Verify the artifact is self-contained and portable:
# (1) ldd shows only system libs - and among them libasound.so.2,
# because audio is left to the OS stack (CoreAudio/WASAPI model),
# (2) no .debug sections remain (strip worked, artifact stays small).
# fontconfig bakes its build prefix into the binary, but that is benign:
# with no config file at that path it falls back to a built-in config
# that scans /usr/share/fonts, so we do NOT fail on those strings.
- name: Verify artifact (ldd, size, alsa is a system lib)
run: |
cd artifact-libmpv
echo "=== dynamic deps (system libs only) ==="
ldd libmpv.so
echo "=== debug sections (expect 0) ==="
readelf -S libmpv.so | grep -c '\.debug' || true
echo "=== size ==="
du -h libmpv.so
echo "=== system audio libs present (pipewire/pulse/alsa, not vendored) ==="
if ldd libmpv.so | grep -Eq 'libpipewire-0\.3|libpulse\.so|libasound\.so'; then
echo "OK: at least one system audio lib present, as intended"
else
echo "ERROR: libmpv.so links no audio backend (no sound?)"
exit 1
fi
- name: Checksums
run: |
cd artifact-libmpv
sha256sum libmpv.so > checksums.txt
cat checksums.txt
- name: Artifact name
id: artifact
run: |
VER=$(cat mpv/MPV_VERSION | tr -d '[:space:]')
# Intermediate artifact is a per-platform directory (zipped by
# upload-artifact) containing libmpv.so + checksums.txt. release.yml
# downloads it and re-uploads the bare .so as the final release asset
# named <name>-<VER>.so.
echo "name=mpv-natives-linux-x86_64" >> "$GITHUB_OUTPUT"
echo "version=$VER" >> "$GITHUB_OUTPUT"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ steps.artifact.outputs.name }}
path: artifact-libmpv
- name: Save ccache
uses: actions/cache/save@v4
if: always()
with:
path: ${{ env.CCACHE_DIR }}
key: ${{ env.TARGET }}-${{ steps.get_time.outputs.timestamp }}