From 4367fb595f0daf22eeb34d5391daf038b139a31b Mon Sep 17 00:00:00 2001 From: 4gray Date: Sat, 18 Jul 2026 00:58:16 +0200 Subject: [PATCH] fix(ci): decouple Linux runtime matrix --- .github/workflows/build-and-make.yaml | 63 ++++++++++++------- docs/architecture/embedded-mpv-native.md | 6 ++ tools/embedded-mpv/README.md | 3 + .../configure-linux-frame-copy-build.test.mjs | 50 +++++++++++++++ 4 files changed, 99 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build-and-make.yaml b/.github/workflows/build-and-make.yaml index ba4661567..5976f3cc7 100644 --- a/.github/workflows/build-and-make.yaml +++ b/.github/workflows/build-and-make.yaml @@ -285,12 +285,12 @@ jobs: if-no-files-found: error retention-days: 7 - build: + build-cross-platform: name: Build on ${{ matrix.os }} ${{ matrix.arch }} - needs: linux-embedded-mpv-runtime runs-on: ${{ matrix.runner }} timeout-minutes: 120 strategy: + fail-fast: false matrix: include: # macOS builds - separate runners to avoid native module conflicts @@ -306,32 +306,14 @@ jobs: embedded_mpv_platform: darwin embedded_mpv_arch: arm64 embedded_mpv_build_runtime: true - # Linux frame-copy profiles and Windows - - os: linux - runner: ubuntu-22.04 - linux_profile: system - embedded_mpv_platform: linux - embedded_mpv_arch: x64 - embedded_mpv_build_runtime: false - - os: linux - runner: ubuntu-22.04 - linux_profile: portable - embedded_mpv_platform: linux - embedded_mpv_arch: x64 - embedded_mpv_build_runtime: false - - os: linux - runner: ubuntu-24.04 - linux_profile: flatpak - embedded_mpv_platform: linux - embedded_mpv_arch: x64 - embedded_mpv_build_runtime: false - os: windows runner: windows-2022 + arch: x64 embedded_mpv_platform: win32 embedded_mpv_arch: x64 embedded_mpv_build_runtime: false - steps: + steps: &electron-build-steps - name: Checkout code uses: actions/checkout@v4 @@ -1112,9 +1094,44 @@ jobs: dist/executables/**/*.blockmap retention-days: 7 + build-linux: + name: Build on ${{ matrix.os }} ${{ matrix.arch }} (${{ matrix.linux_profile }}) + needs: linux-embedded-mpv-runtime + runs-on: ${{ matrix.runner }} + timeout-minutes: 120 + strategy: + fail-fast: false + matrix: + include: + - os: linux + runner: ubuntu-22.04 + arch: x64 + linux_profile: system + embedded_mpv_platform: linux + embedded_mpv_arch: x64 + embedded_mpv_build_runtime: false + - os: linux + runner: ubuntu-22.04 + arch: x64 + linux_profile: portable + embedded_mpv_platform: linux + embedded_mpv_arch: x64 + embedded_mpv_build_runtime: false + - os: linux + runner: ubuntu-24.04 + arch: x64 + linux_profile: flatpak + embedded_mpv_platform: linux + embedded_mpv_arch: x64 + embedded_mpv_build_runtime: false + + steps: *electron-build-steps + create-release: name: Create Draft Release - needs: build + needs: + - build-cross-platform + - build-linux if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }} runs-on: ubuntu-latest permissions: diff --git a/docs/architecture/embedded-mpv-native.md b/docs/architecture/embedded-mpv-native.md index cee3b08fb..6838aee5a 100644 --- a/docs/architecture/embedded-mpv-native.md +++ b/docs/architecture/embedded-mpv-native.md @@ -681,6 +681,12 @@ commit/submodule record, and creates `linux-frame-copy-runtime-sources.tar.xz` for the current repository revision and binary diff with normalized tar metadata. +The workflow keeps the macOS/Windows package matrix independent from the Linux +runtime prerequisite. Only the three Linux profile jobs depend on the runtime +builder; both matrices reuse one YAML-anchored step list to prevent packaging +logic drift. Draft release assembly still requires both matrices, so a public +release cannot silently omit a promised platform. + Windows CI uses a checksum-pinned `win32-x64` runtime archive configured through `IPTVNATOR_WINDOWS_EMBEDDED_MPV_RUNTIME_URL` and `IPTVNATOR_WINDOWS_EMBEDDED_MPV_RUNTIME_SHA256`. Non-tag artifact builds have diff --git a/tools/embedded-mpv/README.md b/tools/embedded-mpv/README.md index 26a593dd9..8e506dd59 100644 --- a/tools/embedded-mpv/README.md +++ b/tools/embedded-mpv/README.md @@ -186,6 +186,9 @@ verifies `system`, `portable`, and `flatpak` independently. Every artifact is extracted for manifest, mode, package-metadata, ELF-isolation, and helper-probe checks. System formats are probed after their declared dependency is installed; Snap and Flatpak also require a sandboxed probe where the runner supports it. +The Linux packaging matrix alone depends on the runtime-builder job. macOS and +Windows use an independent matrix, while both matrices share the same anchored +step list; draft release assembly remains atomic and requires both matrices. The Linux runtime cache contains only staged headers/libraries/manifest plus immutable source inputs: exact downloaded archives (including hwdata), a clean diff --git a/tools/packaging/configure-linux-frame-copy-build.test.mjs b/tools/packaging/configure-linux-frame-copy-build.test.mjs index a076025b3..dde8b74e6 100644 --- a/tools/packaging/configure-linux-frame-copy-build.test.mjs +++ b/tools/packaging/configure-linux-frame-copy-build.test.mjs @@ -2,6 +2,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import test from 'node:test'; +import { parse as parseYaml } from 'yaml'; import { configureLinuxFrameCopyBuild } from './configure-linux-frame-copy-build.mjs'; @@ -17,6 +18,7 @@ const buildWorkflow = fs.readFileSync( path.join(workspaceRoot, '.github', 'workflows', 'build-and-make.yaml'), 'utf8' ); +const buildWorkflowConfig = parseYaml(buildWorkflow); function workflowStep(name) { const marker = ` - name: ${name}\n`; @@ -272,6 +274,54 @@ test('Linux CI builds one cached source runtime and packages three isolated prof assert.match(buildWorkflow, /sourceSha256[\s\S]*source-index\.json/); }); +test('keeps non-Linux builds independent from the Linux runtime prerequisite', () => { + const crossPlatformJob = buildWorkflowConfig.jobs?.['build-cross-platform']; + const linuxJob = buildWorkflowConfig.jobs?.['build-linux']; + + assert.ok(crossPlatformJob); + assert.ok(linuxJob); + assert.equal(crossPlatformJob.needs, undefined); + assert.deepEqual( + crossPlatformJob.strategy.matrix.include.map(({ os, arch }) => ({ + os, + arch, + })), + [ + { os: 'macos', arch: 'x64' }, + { os: 'macos', arch: 'arm64' }, + { os: 'windows', arch: 'x64' }, + ] + ); + assert.equal(crossPlatformJob.strategy['fail-fast'], false); + assert.equal(linuxJob.needs, 'linux-embedded-mpv-runtime'); + assert.deepEqual( + linuxJob.strategy.matrix.include.map( + ({ os, arch, linux_profile: profile }) => ({ + os, + arch, + profile, + }) + ), + [ + { os: 'linux', arch: 'x64', profile: 'system' }, + { os: 'linux', arch: 'x64', profile: 'portable' }, + { os: 'linux', arch: 'x64', profile: 'flatpak' }, + ] + ); + assert.equal( + linuxJob.name, + 'Build on ${{ matrix.os }} ${{ matrix.arch }} (${{ matrix.linux_profile }})' + ); + assert.equal(linuxJob.strategy['fail-fast'], false); + assert.deepEqual(linuxJob.steps, crossPlatformJob.steps); + assert.deepEqual(buildWorkflowConfig.jobs['create-release'].needs, [ + 'build-cross-platform', + 'build-linux', + ]); + assert.match(buildWorkflow, /steps:\s+&electron-build-steps/); + assert.match(buildWorkflow, /steps:\s+\*electron-build-steps/); +}); + test('Linux runtime toolchain installs fontconfig generators without network wraps', () => { const cacheKeyStep = workflowStep( 'Resolve Linux runtime toolchain cache key'