Files
edde746 e9a213807f ci(linux): check the runner's libraries reach the package metadata
The plane added three runtime libraries that bundle-libs.sh deliberately does not
bundle, so they have to be declared per distro by hand - and two hand-maintained
lists drifting apart is the failure this guard exists to prevent.

check_linux_package_deps.py parses the runner's CMake for every pkg-config module
it links, follows target_link_libraries to prove each one actually reaches the
binary, and requires a package name for it in every distro's depends list. It
fails closed on the shapes a naive parser gets wrong: a pkg_check_modules call
naming several modules, options preceding the module name, and version
constraints like mpv>=0.40 that would otherwise be read as a package nobody
ships.

The smoke job builds the three packages and reads the dependencies back out of
the artifacts, deriving what to expect from build-packages.py rather than
restating it - so a library is declared once and verified everywhere. That job is
off by default, which is exactly why it must not carry its own copy of the list.

The Linux native job names libwayland-dev and libegl-dev instead of riding
GTK's and epoxy's transitive dev dependencies, matching the CMake comment's own
rationale. In CI the host-dependency guard runs once: the named step covers the
staged bundle, and build-packages.py's internal run - which exists for by-hand
packaging - is skipped. The smoke job also drops patchelf, which nothing
invokes.
2026-08-10 08:48:14 +02:00

763 lines
28 KiB
YAML

name: CI - Sanity Checks
on:
push:
branches:
- main
# Keep untrusted code on the read-only pull_request event. Never use pull_request_target here.
pull_request:
branches:
- main
workflow_dispatch:
inputs:
build_linux_packages:
description: >
Smoke-build the Linux deb/rpm/pacman packages. Off by default: it needs
a release build plus fpm, and build.yml only packages from main, so this
is the only way to exercise linux/packaging from a branch.
default: false
type: boolean
env:
# Only place this workflow names the SDK; .github/actions/setup-flutter-git pins the same release.
FLUTTER_VERSION: "3.44.0"
jobs:
analyze:
name: Code Analysis
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Setup Flutter
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
pub-cache: false
- name: Cache Pub dependencies
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: |
~/.pub-cache
key: ${{ runner.os }}-pub-v3-${{ hashFiles('**/pubspec.yaml', '**/pubspec.lock') }}
- name: Install dependencies
run: |
flutter pub get
- name: Install wakelock_plus development dependencies
working-directory: packages/wakelock_plus
run: flutter pub get --enforce-lockfile --no-example
- name: Verify generated files committed
run: scripts/codegen.sh --check
- name: Verify translation hygiene
run: python3 scripts/clean_translations.py --check --strict
- name: Verify workflow and script guards
run: bash scripts/ci_guard_checks.sh
- name: Verify formatting
run: |
paths=(lib)
[ ! -d test ] || paths+=(test)
find "${paths[@]}" -name "*.dart" ! -name "*.g.dart" ! -name "*.freezed.dart" -type f -print0 |
xargs -0 -r dart format --output=none --set-exit-if-changed
- name: Verify icon consistency
run: dart run scripts/check_icon_consistency.dart
- name: Analyze code
run: dart run scripts/check_analyzer.dart
- name: Check for unused code
run: |
echo "🔍 Checking for unused code..."
dart run dart_code_linter:metrics check-unused-code lib 2>&1 | tee unused_code.txt
if grep -qi "no unused code found" unused_code.txt; then
echo "✅ No unused code found"
else
echo "❌ Found unused code:"
cat unused_code.txt
exit 1
fi
- name: Check for unused files
run: |
echo "🔍 Checking for unused files..."
dart run dart_code_linter:metrics check-unused-files lib 2>&1 | tee unused_files.txt
if grep -qi "no unused files found" unused_files.txt; then
echo "✅ No unused files found"
else
echo "❌ Found unused files:"
cat unused_files.txt
exit 1
fi
test:
name: Unit Tests
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Setup Flutter
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
pub-cache: false
- name: Cache Pub dependencies
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: |
~/.pub-cache
key: ${{ runner.os }}-pub-v3-${{ hashFiles('**/pubspec.yaml', '**/pubspec.lock') }}
- name: Install dependencies
run: |
flutter clean
flutter pub get
- name: Run tests
run: |
if [ -d "test" ] && [ "$(find test -name '*_test.dart' | wc -l)" -gt 0 ]; then
scripts/run_tests.sh
else
echo "No tests found, skipping test execution"
fi
- name: Install wakelock_plus test dependencies
working-directory: packages/wakelock_plus
run: flutter pub get --enforce-lockfile
- name: Run wakelock_plus VM tests
working-directory: packages/wakelock_plus
run: flutter test test/wakelock_plus_linux_plugin_test.dart
- name: Run wakelock_plus Chrome tests
working-directory: packages/wakelock_plus
run: flutter test --platform chrome --dart-define=WEB_PLUGIN_TESTS=true test/wakelock_plus_web_plugin_test.dart
# The vendored atomic-write patch has to keep the upstream contract, not
# just the new behaviour. Upstream's own suites are the check for that.
- name: Run the vendored desktop preference store tests
run: |
for pkg in shared_preferences_linux shared_preferences_windows; do
(cd "packages/$pkg" && flutter pub get --enforce-lockfile && flutter test)
done
android-test:
name: Android JVM and Native Tests
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Setup Java
uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5
with:
distribution: "temurin"
java-version: "21"
- name: Setup Flutter
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
pub-cache: false
- name: Cache Pub dependencies
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: |
~/.pub-cache
key: ${{ runner.os }}-pub-v3-${{ hashFiles('**/pubspec.yaml', '**/pubspec.lock') }}
- name: Cache Gradle
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Install dependencies
run: flutter pub get
- name: Configure Android local properties
run: printf 'flutter.sdk=%s\nsdk.dir=%s\n' "$FLUTTER_ROOT" "$ANDROID_HOME" > android/local.properties
- name: Configure Android host native tests
run: |
cmake -S android/app/src/test/cpp -B build/android-host-tests \
-DCMAKE_BUILD_TYPE=Debug
- name: Build Android host native tests
run: cmake --build build/android-host-tests --parallel 2
- name: Run Android host native tests
run: |
ctest --test-dir build/android-host-tests \
--output-on-failure --no-tests=error
- name: Run Android JVM unit tests
working-directory: android
run: ./gradlew :app:testDebugUnitTest :saf_util:testDebugUnitTest :libass:testDebugUnitTest -x :app:compileFlutterBuildDebug --continue
- name: Check Android API compatibility
working-directory: android
run: ./gradlew :app:lintDebug
native-format:
name: Native Formatting
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Setup Java
uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5
with:
distribution: "temurin"
java-version: "17"
- name: Verify native formatting
run: scripts/format_native.sh --check
- name: Verify Linux native acquisition and build plan
run: bash linux/packaging/build-libmpv_test.sh
linux-native-test:
name: Linux native reliability (${{ matrix.sanitizer }})
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- sanitizer: address
lifecycle_sanitizers: ON
- sanitizer: thread
lifecycle_sanitizers: OFF
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Setup Flutter
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
pub-cache: false
- name: Install Linux native test dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev \
libstdc++-12-dev libmpv-dev libepoxy-dev libcurl4-openssl-dev libevdev-dev \
libwayland-dev libegl-dev
- name: Prepare Flutter Linux configuration
run: |
flutter pub get --enforce-lockfile --no-example
flutter build linux --debug --config-only --no-pub
- name: Configure Linux native reliability tests
run: |
cmake -S linux -B build/linux-native-${{ matrix.sanitizer }} -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DPLEZY_BUILD_MPV_PLAYER_LIFECYCLE_TESTS=ON \
-DPLEZY_MPV_LIFECYCLE_SANITIZERS=${{ matrix.lifecycle_sanitizers }} \
-DPLEZY_BUILD_MPV_RELIABILITY_TESTS=ON \
-DPLEZY_MPV_RELIABILITY_SANITIZER=${{ matrix.sanitizer }}
# `plezy` is the runner itself. Without it nothing in CI ever compiles
# my_application.cc, mpv_plugin.cc or the Wayland video plane — the
# reliability test targets each pull in only a couple of translation units,
# so a break in the rest of linux/runner reached a release build unseen.
- name: Build Linux native reliability tests
run: |
cmake --build build/linux-native-${{ matrix.sanitizer }} --parallel 2 --target \
plezy \
mpv_player_lifecycle_test \
mpv_player_hdr_output_test \
mpv_property_result_contract_test \
hdr_metadata_test \
plane_geometry_test \
video_params_test
- name: Run Linux native reliability tests
run: |
ctest --test-dir build/linux-native-${{ matrix.sanitizer }} \
--output-on-failure --no-tests=error
apple-native-test:
name: Apple native reliability (${{ matrix.platform }})
runs-on: macos-26
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- platform: iOS
project_directory: ios
workspace: ios/Runner.xcworkspace
simulator_runtime: iOS
simulator_platform: iOS
static_destination: ""
- platform: macOS
project_directory: macos
workspace: macos/Runner.xcworkspace
simulator_runtime: ""
simulator_platform: ""
static_destination: platform=macOS
- platform: tvOS
project_directory: tvos
workspace: tvos/Runner.xcworkspace
simulator_runtime: tvOS
simulator_platform: tvOS
static_destination: ""
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Setup Flutter
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
pub-cache: false
- name: Install locked Dart dependencies
run: flutter pub get --enforce-lockfile --no-example
- name: Record committed CocoaPods lockfile
if: matrix.platform != 'tvOS'
env:
PODFILE_LOCK: ${{ matrix.project_directory }}/Podfile.lock
run: |
test -f "$PODFILE_LOCK"
shasum -a 256 "$PODFILE_LOCK" > "$RUNNER_TEMP/plezy-podfile-lock.sha256"
- name: Prepare iOS Flutter build settings
if: matrix.platform == 'iOS'
run: flutter build ios --config-only --simulator --debug --no-pub
- name: Prepare macOS Flutter build settings
if: matrix.platform == 'macOS'
run: flutter build macos --config-only --debug --no-pub
- name: Prepare tvOS Flutter engine
if: matrix.platform == 'tvOS'
run: tvos/scripts/fetch_engine.sh
- name: Verify Flutter configuration preserved CocoaPods lockfile
if: matrix.platform != 'tvOS'
run: shasum -a 256 --check "$RUNNER_TEMP/plezy-podfile-lock.sha256"
- name: Install locked CocoaPods dependencies
if: matrix.platform != 'tvOS'
working-directory: ${{ matrix.project_directory }}
run: pod install --deployment
- name: Install tvOS CocoaPods dependencies
if: matrix.platform == 'tvOS'
run: tvos/scripts/pod_install.sh
- name: Verify tvOS project wiring
if: matrix.platform == 'tvOS'
run: ruby tvos/scripts/test_wire_mpv.rb
- name: Select Apple test destination
env:
SIMULATOR_RUNTIME: ${{ matrix.simulator_runtime }}
SIMULATOR_PLATFORM: ${{ matrix.simulator_platform }}
STATIC_DESTINATION: ${{ matrix.static_destination }}
run: |
python3 - <<'PY'
import json
import os
import subprocess
destination = os.environ["STATIC_DESTINATION"]
if not destination:
runtime_name = os.environ["SIMULATOR_RUNTIME"]
payload = json.loads(
subprocess.check_output(
["xcrun", "simctl", "list", "devices", "available", "-j"],
text=True,
)
)
devices = [
device
for runtime, candidates in payload["devices"].items()
if f".{runtime_name}-" in runtime
for device in candidates
if device.get("isAvailable", False)
]
if not devices:
raise SystemExit(f"no available {runtime_name} simulator")
destination = (
f"platform={os.environ['SIMULATOR_PLATFORM']} Simulator,"
f"id={devices[0]['udid']}"
)
with open(os.environ["GITHUB_ENV"], "a", encoding="utf-8") as output:
output.write(f"APPLE_TEST_DESTINATION={destination}\n")
PY
- name: Run Apple native reliability tests
run: |
xcodebuild test \
-workspace "${{ matrix.workspace }}" \
-scheme Runner \
-configuration Debug \
-destination "$APPLE_TEST_DESTINATION" \
-disableAutomaticPackageResolution \
CODE_SIGNING_ALLOWED=NO \
COMPILER_INDEX_STORE_ENABLE=NO
windows-native-test:
name: Windows native reliability (${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- arch: x64
runner: windows-latest
flutter_setup: action
- arch: arm64
runner: windows-11-arm
flutter_setup: git
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Install 7-Zip
if: matrix.arch == 'arm64'
shell: pwsh
run: choco install 7zip -y
- name: Setup Flutter
if: matrix.flutter_setup == 'action'
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
pub-cache: false
- name: Set up Flutter from its pinned commit
if: matrix.flutter_setup == 'git'
uses: ./.github/actions/setup-flutter-git
- name: Install locked Dart dependencies
shell: pwsh
run: flutter pub get --enforce-lockfile --no-example
# Windows replacement semantics (`MoveFileExW` with
# MOVEFILE_REPLACE_EXISTING) cannot be proven on the POSIX runners, and a
# memory file system proves nothing about either. The vendored
# shared_preferences_windows store write is the fix for #1732, so exercise
# it here, on a real NTFS volume, against the real backend.
- name: Run the vendored Windows preference store tests
shell: pwsh
run: flutter test test/services/prefs_store_atomic_write_windows_test.dart
- name: Install patched Flutter engine
shell: pwsh
run: |
flutter precache --windows
.\windows\tool\install-patched-engine.ps1
- name: Prepare Flutter Windows configuration
shell: pwsh
run: flutter build windows --debug --config-only --no-pub
- name: Configure Windows native reliability tests
shell: pwsh
run: |
$buildDir = "build/windows/${{ matrix.arch }}"
cmake -S windows -B $buildDir `
-DPLEZY_BUILD_MPV_PROPERTY_CONTRACT_TESTS=ON `
-DPLEZY_BUILD_DISPLAY_RECOVERY_TESTS=ON
- name: Build Windows native reliability tests
shell: pwsh
run: |
$buildDir = "build/windows/${{ matrix.arch }}"
cmake --build $buildDir --config Debug --parallel 2 --target `
mpv_property_result_contract_test `
mpv_player_property_contract_test `
display_mode_manager_test
- name: Run Windows native reliability tests
shell: pwsh
run: |
$buildDir = "build/windows/${{ matrix.arch }}"
ctest --test-dir "$buildDir/runner" -C Debug --output-on-failure --no-tests=error
dependency-check:
name: Dependency Validation
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Setup Flutter
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
pub-cache: false
- name: Cache Pub dependencies
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: |
~/.pub-cache
key: ${{ runner.os }}-pub-v3-${{ hashFiles('**/pubspec.yaml', '**/pubspec.lock') }}
- name: Verify dependencies
run: |
flutter clean
flutter pub get
flutter pub outdated
server:
name: Server checks
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Setup Go
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6
with:
go-version-file: server/go.mod
cache-dependency-path: server/go.sum
- name: Run server checks
run: scripts/ci_server_checks.sh
website:
name: Website checks
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: "1.3.14"
- name: Run website checks
run: scripts/ci_website_checks.sh
# The only job that checks packaging against a real artifact. build.yml also
# packages Linux, but refuses any ref but refs/heads/main, and
# check_linux_package_deps.py can only compare a hand-written list against
# CMake - it cannot prove the list reaches the artifact, nor see the
# transitive libraries the bundled libmpv drags in. This can, by reading the
# built bundle back with ldd.
#
# Runs on every push to main and on request, but not on pull requests: it
# needs a release build plus fpm, which is minutes of runner time that most
# changes here have no reason to pay. That buys post-merge detection rather
# than pre-merge, which is the deliberate trade. Dispatch it from a branch
# with build_linux_packages when touching linux/packaging - which is the only
# way to exercise it before merging.
linux-packages:
name: Linux package smoke build
if: ${{ inputs.build_linux_packages || github.event_name == 'push' }}
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Setup Flutter
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
pub-cache: false
# The packaging deps, minus libmpv: this job builds it from source below,
# because the distro's is a different version with different windowing
# backends, and a package smoke-built against it cannot show that
# build-libmpv.sh still works or that the bundle it produces is coherent.
- name: Install packaging dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
clang cmake meson ninja-build pkg-config nasm libgtk-3-dev liblzma-dev \
libstdc++-12-dev libepoxy-dev libcurl4-openssl-dev libevdev-dev \
libasound2-dev libass-dev libfreetype-dev libfontconfig-dev libfribidi-dev \
libharfbuzz-dev libegl-dev libgl-dev libgnutls28-dev libpipewire-0.3-dev \
libva-dev libxkbcommon-dev libpulse-dev libdbus-1-dev libdrm-dev \
libgbm-dev libwayland-dev wayland-protocols liblcms2-dev libmujs-dev \
liblua5.2-dev rpm libarchive-tools imagemagick ruby-dev build-essential
sudo gem install fpm --version 1.17.0 --no-document
# Keyed the same way build.yml keys it, so editing the script or its pinned
# inputs is what invalidates the cache - and this branch's whole point is
# that those edits get exercised somewhere.
- name: Cache libmpv build
id: libmpv-cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: libmpv-prefix
key: ci-libmpv-${{ runner.arch }}-${{ hashFiles('linux/packaging/build-libmpv.sh', 'linux/packaging/native-inputs.json') }}
- name: Build libmpv
if: steps.libmpv-cache.outputs.cache-hit != 'true'
run: bash linux/packaging/build-libmpv.sh
# The windowing backends the runner depends on, read off the library the
# script just produced. The plane hands mpv MPV_RENDER_PARAM_WL_DISPLAY, so
# a libmpv without Wayland cannot find the VAAPI device and quietly decodes
# in software; X11 and VDPAU are gone with the texture path.
- name: Check the built libmpv's backends
run: |
LIB=$(find libmpv-prefix -name 'libmpv.so.2' | head -1)
echo "== $LIB =="
ldd "$LIB" | grep -iE 'wayland|libX11|vdpau' || echo '(none)'
ldd "$LIB" | grep -q libwayland-client || {
echo "::error::the built libmpv does not link libwayland-client, so the video plane cannot work"
exit 1
}
- name: Build the release bundle
run: |
flutter pub get --enforce-lockfile --no-example
flutter build linux --release
env:
PKG_CONFIG_PATH: ${{ github.workspace }}/libmpv-prefix/lib/pkgconfig:${{ github.workspace }}/libmpv-prefix/lib/x86_64-linux-gnu/pkgconfig
# Mirrors build.yml: resolve the bundle completely, then package from it.
# libmpv travels with us, so nothing depends on a host one - which also
# removes the transitive pull of everything libmpv links, hence bundle-libs
# before packaging rather than after.
- name: Copy libmpv into the bundle
run: |
BUNDLE_LIB=build/linux/x64/release/bundle/lib
LIBMPV_DIR=$(dirname "$(find libmpv-prefix -name 'libmpv.so' | head -1)")
cp -a "$LIBMPV_DIR"/libmpv.so* "$BUNDLE_LIB/"
cp -a libmpv-prefix/lib/libshaderc_shared.so* "$BUNDLE_LIB/"
- name: Bundle shared libraries
run: bash linux/packaging/bundle-libs.sh build/linux/x64/release/bundle
- name: Copy wrapper script into the bundle
run: cp linux/packaging/plezy.sh build/linux/x64/release/bundle/plezy.sh
# Derives what the resolved bundle still needs from the host and proves
# every one of those libraries is declared. This is the check that would
# have caught bundling libmpv without also declaring what libmpv links.
- name: Verify every unbundled library the bundle needs is declared
run: python3 linux/packaging/check-bundle-host-deps.py build/linux/x64/release/bundle
# OUTPUT_DIR defaults to the repo root; name it so the paths below are not
# a guess about where fpm dropped things. The host-dependency guard is
# skipped because the named step above just ran it against this same
# bundle; the internal run exists for by-hand packaging outside CI.
- name: Build the packages
run: |
mkdir -p "$OUTPUT_DIR"
python3 linux/packaging/build-packages.py
env:
OUTPUT_DIR: ${{ github.workspace }}/packages
PLEZY_SKIP_HOST_DEP_CHECK: "1"
# The guard above reconciles the depends lists with the staged bundle; only
# the packages themselves can show that list survived fpm. Every name comes
# from build-packages.py, so adding a library there is verified here without
# a second edit - and this job is off by default, so a hand-copied list
# would rot unseen. The release job in build.yml runs the same script
# against the artifacts users install, so the assertions cannot drift.
- name: Verify the declared dependencies reached the package metadata
run: python3 linux/packaging/check-package-deps.py "${{ github.workspace }}/packages"
# Same resolved bundle the packages were cut from, so the tarball is not a
# second, differently-assembled artifact. It is the one to put on a USB for
# a foreign machine, because it needs nothing installed.
- name: Create the tarball
run: |
BUNDLE_DIR=build/linux/x64/release/bundle
mkdir -p "$OUTPUT_DIR"
tar -czf "$OUTPUT_DIR/plezy-linux-x64.tar.gz" -C "$BUNDLE_DIR" .
echo "=== libmpv travelling in every artifact ==="
ldd "$BUNDLE_DIR/lib/libmpv.so" | grep -iE 'wayland|libX11|vdpau' || echo '(none)'
env:
OUTPUT_DIR: ${{ github.workspace }}/packages
- name: Upload the packages
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: linux-packages-smoke
path: ${{ github.workspace }}/packages/plezy-linux-x64.*
if-no-files-found: error
retention-days: 7