diff --git a/.github/workflows/build-vapoursynth.yml b/.github/workflows/build-vapoursynth.yml new file mode 100644 index 000000000000..1c149d88b1e1 --- /dev/null +++ b/.github/workflows/build-vapoursynth.yml @@ -0,0 +1,174 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# This workflow is based on the `build-wheel` job (linux_x86_64/linux_aarch64 +# legs) of https://github.com/vapoursynth/vapoursynth/blob/R81/.github/workflows/build.yml +name: Build vapoursynth wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'Version glob to (re)build; empty builds every version of docs/packages/vapoursynth.yaml not released yet' + required: false + default: '' + pull_request: + branches: [main] + paths: + - '.github/workflows/build-vapoursynth.yml' + - 'docs/packages/vapoursynth.yaml' + - 'patches/vapoursynth/**' + push: + branches: [main] + paths: + - '.github/workflows/build-vapoursynth.yml' + - 'docs/packages/vapoursynth.yaml' + - 'patches/vapoursynth/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + with: + package: vapoursynth + version: ${{ inputs.version }} + + # One cp312-abi3 wheel: meson-python's limited-api=true builds it once and + # cibuildwheel reuses+tests it on cp313/cp314 (find_compatible_wheel). + build_abi3: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + name: Build vapoursynth ${{ matrix.version }} cp312-abi3-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + timeout-minutes: 180 + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + + env: + VAPOURSYNTH_VERSION: ${{ matrix.version }} + + steps: + - name: Checkout vapoursynth R${{ env.VAPOURSYNTH_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: vapoursynth/vapoursynth + ref: R${{ env.VAPOURSYNTH_VERSION }} + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + # glslang, Vulkan-Headers, libp2p and zimg are meson-wrap subprojects + # fetched and statically linked in at build time; none of their + # licences are in this checkout. glslang/Vulkan-Headers pin a tag + # (subprojects/*.wrap); libp2p/zimg pin revision = HEAD, so their + # notice is staged from the default branch, same lack of pinning as + # upstream's own build. + - name: Stage the vendored subprojects' licences + run: | + set -euo pipefail + curl -fsSL --retry 5 "https://raw.githubusercontent.com/KhronosGroup/glslang/vulkan-sdk-1.4.357.0/LICENSE.txt" -o LICENSE.glslang + curl -fsSL --retry 5 "https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/vulkan-sdk-1.4.357.0/LICENSE.md" -o LICENSE.vulkan-headers + curl -fsSL --retry 5 "https://raw.githubusercontent.com/sekrit-twc/libp2p/master/COPYING" -o COPYING.libp2p + curl -fsSL --retry 5 "https://raw.githubusercontent.com/sekrit-twc/zimg/master/COPYING" -o COPYING.zimg + + - name: Apply patches + run: git apply python-wheels/patches/vapoursynth/${{ env.VAPOURSYNTH_VERSION }}/*.patch + + - uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 + env: + CIBW_ARCHS: riscv64 + CIBW_BUILD: 'cp312-* cp313-* cp314-*' + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: vapoursynth-${{ env.VAPOURSYNTH_VERSION }}-cp312-abi3-manylinux_riscv64 + path: ./wheelhouse/*.whl + if-no-files-found: error + + # Free-threaded wheel: upstream's own `cp3??t-*` override disables + # meson-python's limited-api, so cp314t needs its own per-interpreter + # build. Upstream's own build list names cp315t; our riscv64 image has + # cp314t but no cp315t (gotcha 11). + build_freethreaded: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + name: Build vapoursynth ${{ matrix.version }} cp314t-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + timeout-minutes: 180 + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + + env: + VAPOURSYNTH_VERSION: ${{ matrix.version }} + + steps: + - name: Checkout vapoursynth R${{ env.VAPOURSYNTH_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: vapoursynth/vapoursynth + ref: R${{ env.VAPOURSYNTH_VERSION }} + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + - name: Stage the vendored subprojects' licences + run: | + set -euo pipefail + curl -fsSL --retry 5 "https://raw.githubusercontent.com/KhronosGroup/glslang/vulkan-sdk-1.4.357.0/LICENSE.txt" -o LICENSE.glslang + curl -fsSL --retry 5 "https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/vulkan-sdk-1.4.357.0/LICENSE.md" -o LICENSE.vulkan-headers + curl -fsSL --retry 5 "https://raw.githubusercontent.com/sekrit-twc/libp2p/master/COPYING" -o COPYING.libp2p + curl -fsSL --retry 5 "https://raw.githubusercontent.com/sekrit-twc/zimg/master/COPYING" -o COPYING.zimg + + - name: Apply patches + run: git apply python-wheels/patches/vapoursynth/${{ env.VAPOURSYNTH_VERSION }}/*.patch + + - uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 + env: + CIBW_ARCHS: riscv64 + CIBW_BUILD: 'cp314t-*' + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: vapoursynth-${{ env.VAPOURSYNTH_VERSION }}-cp314t-manylinux_riscv64 + path: ./wheelhouse/*.whl + if-no-files-found: error + + publish: + name: Publish vapoursynth ${{ matrix.version }} + needs: [setup, build_abi3, build_freethreaded] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + permissions: + contents: write + pull-requests: write + uses: $/.github/workflows/_publish-wheel.yml + secrets: + app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }} + with: + artifact-pattern: vapoursynth-${{ matrix.version }}-*-manylinux_riscv64 diff --git a/docs/packages/vapoursynth.yaml b/docs/packages/vapoursynth.yaml new file mode 100644 index 000000000000..36864b3e1b59 --- /dev/null +++ b/docs/packages/vapoursynth.yaml @@ -0,0 +1,5 @@ +package-name: vapoursynth +source-code: https://github.com/vapoursynth/vapoursynth +license: LGPL-2.1-or-later +versions: +- version: '81' diff --git a/patches/vapoursynth/81/0001-Ship-the-statically-embedded-subprojects-licences-in.patch b/patches/vapoursynth/81/0001-Ship-the-statically-embedded-subprojects-licences-in.patch new file mode 100644 index 000000000000..c6aa232ff38a --- /dev/null +++ b/patches/vapoursynth/81/0001-Ship-the-statically-embedded-subprojects-licences-in.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 15 Oct 2026 23:54:36 +0000 +Subject: [PATCH] Ship the statically-embedded subprojects' licences in wheel + metadata + +glslang, Vulkan-Headers, libp2p and zimg are meson-wrap subprojects +fetched and compiled in at build time (glslang "embedded statically +and always present" per meson.build; libp2p/zimg linked into the core +unconditionally); none of their licences are in this checkout or in +the wheel. license-files is an explicit list here, so there is no +default glob to extend it with - widen the list directly to add +LICENSE.glslang, LICENSE.vulkan-headers, COPYING.libp2p and +COPYING.zimg, staged at the project root by the workflow from each +subproject's own release tag (pinned for glslang/Vulkan-Headers; +libp2p/zimg's wraps pin revision = HEAD, so their notice is fetched +from the default branch, same lack of pinning as upstream's own build). + +Upstream-Status: To upstream [not submitted from this automated port run] +--- + pyproject.toml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/pyproject.toml b/pyproject.toml +index 46700e2..6049406 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -8,7 +8,7 @@ description = "A frameserver for the 21st century" + readme = "README.md" + requires-python = ">=3.12" + license = "LGPL-2.1-or-later" +-license-files = ["COPYING.LESSER"] ++license-files = ["COPYING.LESSER", "LICENSE.glslang", "LICENSE.vulkan-headers", "COPYING.libp2p", "COPYING.zimg"] + authors = [{ name = "Fredrik Mellbin", email = "fredrik.mellbin@gmail.com" }] + keywords = ["frameserver", "video", "audio"] + classifiers = [