- Install ffnvcodec headers everywhere the project FFmpeg is built (distro packages on Debian/Ubuntu/Arch/MSYS2, nv-codec-headers from source on Fedora) so the FFmpeg build picks up NVDEC/NVENC. - ocio-sys 0.2.1's vendored yaml-cpp misses <cstdint> and fails on GCC >= 16 (measured on GCC 16.2.1); patch the dependency to the fixed upstream tree (shaloong/ocio-rs, 933c65dc) until a fixed release lands on crates.io. - New tooling/ocio-env.sh decides the OCIO build env per job: system OCIO >= 2.5 when present (static when the package ships libOpenColorIO.a, dynamic otherwise), vendored static build as the fallback. The Arch package gains an 'opencolorio' dependency only when the binaries link the system OCIO (build-pkg.sh probes ldd). - CI 'Build' steps switch from cargo build to cargo check: the Test step links the test binaries anyway, and a full build would codegen every workspace crate twice.
453 lines
17 KiB
YAML
453 lines
17 KiB
YAML
name: CD
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*'
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
# ------------------------------------------------------------------
|
|
# Linux: deb + AppImage + pacman in one job. cargo-packager does not
|
|
# support rpm (its format list is deb/appimage/pacman/nsis/dmg/app/wix),
|
|
# and its "pacman" format emits a PKGBUILD + source tarball rather than a
|
|
# compiled pkg.tar.zst — both are upstream limitations.
|
|
# ------------------------------------------------------------------
|
|
# ------------------------------------------------------------------
|
|
# Linux: one native package per distro, each built INSIDE that
|
|
# distro's container so the declared dependencies always resolve to
|
|
# the distro's own package names (dpkg-shlibdeps / rpmbuild
|
|
# auto-requires / Arch static base list). deb: hand-rolled dpkg-deb;
|
|
# rpm: rpmbuild; arch: makepkg. AppImage stays on the Ubuntu runner
|
|
# (self-contained by design).
|
|
# ------------------------------------------------------------------
|
|
linux:
|
|
name: Linux packages (${{ matrix.distro }})
|
|
runs-on: warp-ubuntu-latest-x64-8x
|
|
container: ${{ matrix.image }}
|
|
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- distro: debian
|
|
image: debian:12
|
|
- distro: fedora
|
|
image: fedora:41
|
|
- distro: arch
|
|
image: archlinux:latest
|
|
|
|
steps:
|
|
# git/curl must land BEFORE actions/checkout runs inside the
|
|
# container.
|
|
- name: Install git and fetch tools
|
|
run: |
|
|
case "${{ matrix.distro }}" in
|
|
debian) apt-get update && apt-get install -y git curl ;;
|
|
fedora) dnf install -y git curl ;;
|
|
arch) pacman -Sy --noconfirm git curl ;;
|
|
esac
|
|
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
submodules: true
|
|
|
|
- name: Install Rust (stable)
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Install system dependencies
|
|
run: |
|
|
case "${{ matrix.distro }}" in
|
|
debian)
|
|
apt-get install -y \
|
|
build-essential cmake pkg-config nasm dpkg-dev \
|
|
libpipewire-0.3-dev libspa-0.2-dev libjack-jackd2-dev \
|
|
libasound2-dev libpulse-dev libsndfile1-dev \
|
|
libgl1-mesa-dev libgl1-mesa-dri mesa-vulkan-drivers \
|
|
libvulkan-dev libxkbcommon-dev libxkbcommon-x11-dev \
|
|
librsvg2-bin libffnvcodec-dev libopencolorio-dev
|
|
;;
|
|
fedora)
|
|
dnf install -y \
|
|
gcc gcc-c++ cmake pkgconf-pkg-config nasm \
|
|
pipewire-devel jack-audio-connection-kit-devel \
|
|
alsa-lib-devel pulseaudio-libs-devel libsndfile-devel \
|
|
mesa-libGL-devel mesa-vulkan-drivers \
|
|
vulkan-headers vulkan-loader-devel \
|
|
libxkbcommon-devel libxkbcommon-x11-devel \
|
|
rpm-build librsvg2-tools OpenColorIO-devel
|
|
# ffnvcodec headers (NVDEC for the project FFmpeg build) are
|
|
# not in Fedora's base repos (RPM Fusion only); they are
|
|
# distribution-free headers, so install them from source.
|
|
git clone --depth 1 https://git.videolan.org/git/ffmpeg/nv-codec-headers.git /tmp/nv-codec-headers
|
|
make -C /tmp/nv-codec-headers install PREFIX=/usr
|
|
;;
|
|
arch)
|
|
pacman -S --needed --noconfirm \
|
|
base-devel cmake pkgconf nasm \
|
|
pipewire jack2 alsa-lib libpulse libsndfile \
|
|
mesa vulkan-headers vulkan-icd-loader \
|
|
libxkbcommon libxkbcommon-x11 librsvg \
|
|
ffnvcodec-headers opencolorio
|
|
;;
|
|
esac
|
|
|
|
- name: Configure build environment
|
|
run: |
|
|
# tooling/ocio-env.sh: use a system OCIO >= 2.5 when present
|
|
# (vendored 2.5.2 fails on GCC >= 16), static when the package
|
|
# ships libOpenColorIO.a; otherwise the vendored static build.
|
|
tooling/ocio-env.sh >> "$GITHUB_ENV"
|
|
|
|
# TEMP: cache disabled until the Gitea instance cache is provisioned (Cache cargo artifacts)
|
|
# uses: Swatinem/rust-cache@v2
|
|
# with:
|
|
# shared-key: oak-${{ matrix.distro }}
|
|
# cache-on-failure: true
|
|
|
|
# TEMP: cache disabled until the Gitea instance cache is provisioned (Cache project FFmpeg)
|
|
# uses: actions/cache@v4
|
|
# with:
|
|
# path: .cache/ffmpeg
|
|
# key: ffmpeg-${{ matrix.distro }}-${{ hashFiles('tooling/ffmpeg/build-ffmpeg.sh') }}
|
|
|
|
- name: Build project FFmpeg (static, GPL + free codecs + hwaccel)
|
|
run: tooling/ffmpeg/build-ffmpeg.sh
|
|
|
|
- name: Build (release)
|
|
run: cargo build --release --locked
|
|
|
|
- name: Generate app icon (PNG from Oak_Icon.svg)
|
|
run: rsvg-convert -w 512 -h 512 Oak_Icon.svg -o icons/icon.png
|
|
|
|
- name: Package
|
|
run: |
|
|
set -euo pipefail
|
|
# The release version lives in [workspace.package] of the root
|
|
# Cargo.toml (single source of truth; tags do not carry it).
|
|
VERSION=$(sed -n '/^\[workspace\.package\]/,/^\[/s/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)
|
|
case "${{ matrix.distro }}" in
|
|
debian) tooling/package/build-deb.sh "$VERSION" ;;
|
|
fedora) tooling/package/build-rpm.sh "$VERSION" ;;
|
|
arch) tooling/package/build-pkg.sh "$VERSION" ;;
|
|
esac
|
|
shell: bash
|
|
|
|
- name: Upload artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: oak-linux-${{ matrix.distro }}
|
|
path: |
|
|
target/release/*.deb
|
|
target/release/*.rpm
|
|
target/release/*.pkg.tar.zst
|
|
if-no-files-found: error
|
|
|
|
# ------------------------------------------------------------------
|
|
# AppImage (self-contained; cargo-packager on the Ubuntu runner).
|
|
# ------------------------------------------------------------------
|
|
appimage:
|
|
name: Linux AppImage
|
|
runs-on: warp-ubuntu-latest-x64-8x
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
submodules: true
|
|
|
|
- name: Install Rust (stable)
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Install system dependencies
|
|
run: |
|
|
tooling/install-deps.sh
|
|
sudo apt-get install -y \
|
|
cmake librsvg2-bin \
|
|
libpipewire-0.3-dev libspa-0.2-dev libjack-jackd2-dev \
|
|
libasound2-dev libpulse-dev libsndfile1-dev \
|
|
libgl1-mesa-dev libgl1-mesa-dri mesa-vulkan-drivers \
|
|
libvulkan-dev libxkbcommon-dev libxkbcommon-x11-dev \
|
|
libffnvcodec-dev libopencolorio-dev
|
|
|
|
- name: Configure build environment
|
|
run: tooling/ocio-env.sh >> "$GITHUB_ENV"
|
|
|
|
# TEMP: cache disabled until the Gitea instance cache is provisioned (Cache cargo artifacts)
|
|
# uses: Swatinem/rust-cache@v2
|
|
# with:
|
|
# shared-key: oak-appimage
|
|
# cache-on-failure: true
|
|
|
|
# TEMP: cache disabled until the Gitea instance cache is provisioned (Cache project FFmpeg)
|
|
# uses: actions/cache@v4
|
|
# with:
|
|
# path: .cache/ffmpeg
|
|
# key: ffmpeg-appimage-${{ hashFiles('tooling/ffmpeg/build-ffmpeg.sh') }}
|
|
|
|
- name: Build project FFmpeg (static, GPL + free codecs + hwaccel)
|
|
run: tooling/ffmpeg/build-ffmpeg.sh
|
|
|
|
- name: Install cargo-packager
|
|
run: cargo install cargo-packager --locked
|
|
|
|
- name: Generate app icon (PNG from Oak_Icon.svg)
|
|
run: |
|
|
mkdir -p icons
|
|
rsvg-convert -w 512 -h 512 Oak_Icon.svg -o icons/icon.png
|
|
file icons/icon.png
|
|
|
|
- name: Build (release)
|
|
run: cargo build --release --locked
|
|
|
|
- name: Package (AppImage)
|
|
run: cargo packager --release --formats appimage
|
|
|
|
- name: Upload artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: oak-linux-appimage
|
|
path: target/release/*.AppImage
|
|
if-no-files-found: error
|
|
|
|
macos:
|
|
name: macOS DMG (Apple Silicon)
|
|
runs-on: warp-macos-15-arm64-6x
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
submodules: true
|
|
|
|
- name: Install Rust (stable)
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Install system dependencies
|
|
run: |
|
|
tooling/install-deps.sh
|
|
brew install cmake librsvg
|
|
|
|
- name: Configure build environment
|
|
run: |
|
|
{
|
|
# OCIO comes from the ocio-sys vendored source build (same on
|
|
# every platform); no OCIO_INSTALL_DIR override.
|
|
echo "OCIO_RS_ENABLE_REAL=1"
|
|
echo "OCIO_RS_LINK=static"
|
|
echo "CFLAGS=-I/opt/homebrew/include"
|
|
echo "LDFLAGS=-L/opt/homebrew/lib"
|
|
echo "PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig/openjpeg"
|
|
} >> "$GITHUB_ENV"
|
|
|
|
# TEMP: cache disabled until the Gitea instance cache is provisioned (Cache cargo artifacts)
|
|
# uses: Swatinem/rust-cache@v2
|
|
# with:
|
|
# shared-key: oak-workspace
|
|
# cache-on-failure: true
|
|
|
|
# TEMP: cache disabled until the Gitea instance cache is provisioned (Cache project FFmpeg)
|
|
# uses: actions/cache@v4
|
|
# with:
|
|
# path: .cache/ffmpeg
|
|
# key: ffmpeg-${{ runner.os }}-${{ hashFiles('tooling/ffmpeg/build-ffmpeg.sh') }}
|
|
|
|
- name: Build project FFmpeg (static, GPL + free codecs + hwaccel)
|
|
run: |
|
|
tooling/ffmpeg/build-ffmpeg.sh
|
|
echo "FFMPEG_DIR=$PWD/.cache/ffmpeg" >> "$GITHUB_ENV"
|
|
|
|
- name: Install cargo-packager
|
|
run: cargo install cargo-packager --locked
|
|
|
|
- name: Generate app icon (PNG from Oak_Icon.svg)
|
|
run: |
|
|
mkdir -p icons
|
|
# cargo-packager's tauri-icns 0.1.0 maps only 512x512@1x (and
|
|
# 1024x1024@2x); a plain 1024x1024 PNG aborts with "No matching
|
|
# IconType", so render 512x512.
|
|
rsvg-convert -w 512 -h 512 Oak_Icon.svg -o icons/icon.png
|
|
file icons/icon.png
|
|
|
|
# Build the packaged binaries (default members: the app, oak-cli,
|
|
# oak-worker).
|
|
- name: Build (release)
|
|
run: cargo build --release --locked
|
|
|
|
- name: Package .app bundle
|
|
run: cargo packager --release --formats app
|
|
|
|
# Pull the Homebrew dylibs the binaries reference into
|
|
# Contents/Frameworks and rewrite install names to
|
|
# @executable_path-relative (the script ad-hoc re-signs the bundle).
|
|
- name: Bundle dylibs into the .app
|
|
run: tooling/package/bundle-dylibs-macos.sh target/release/Oak.app
|
|
|
|
- name: Create DMG
|
|
run: |
|
|
rm -rf dmg-staging
|
|
mkdir -p dmg-staging
|
|
cp -R target/release/Oak.app dmg-staging/
|
|
ln -s /Applications dmg-staging/Applications
|
|
hdiutil create -volname "Oak Video Editor" \
|
|
-srcfolder dmg-staging -ov -format UDZO Oak-macOS-arm64.dmg
|
|
|
|
- name: Upload artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: oak-macos
|
|
path: Oak-macOS-arm64.dmg
|
|
if-no-files-found: error
|
|
|
|
# ------------------------------------------------------------------
|
|
# Windows: NSIS installer (restored; cargo-packager downloads its own
|
|
# makensis, SHA-1 verified). The obsolete `-p oakengine` cdylib prebuild
|
|
# from before M14 R4 is dropped — no packaged binary links the cdylib.
|
|
# ------------------------------------------------------------------
|
|
windows:
|
|
name: Windows installer (NSIS)
|
|
runs-on: warp-windows-latest-x64-16x
|
|
|
|
defaults:
|
|
run:
|
|
shell: msys2 {0}
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
submodules: true
|
|
|
|
- name: Install Rust (stable)
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Setup MSYS2
|
|
uses: msys2/setup-msys2@v2
|
|
with:
|
|
msystem: UCRT64
|
|
update: true
|
|
# MSYS2's own Rust targets x86_64-pc-windows-gnu by default —
|
|
# the Windows build is GNU-target (the MSVC linker rejects the
|
|
# Unix-style link args the build scripts emit).
|
|
install: >-
|
|
git
|
|
mingw-w64-ucrt-x86_64-gcc
|
|
mingw-w64-ucrt-x86_64-rust
|
|
|
|
- name: Install system dependencies
|
|
run: |
|
|
bash tooling/install-deps.sh
|
|
pacman -S --needed --noconfirm \
|
|
mingw-w64-ucrt-x86_64-cmake \
|
|
mingw-w64-ucrt-x86_64-opencolorio \
|
|
mingw-w64-ucrt-x86_64-librsvg \
|
|
mingw-w64-ucrt-x86_64-ffnvcodec-headers \
|
|
mingw-w64-ucrt-x86_64-pkgconf
|
|
|
|
- name: Configure build environment
|
|
run: |
|
|
# System OCIO (MSYS2, the exact 2.5.2 the bridge targets);
|
|
# tooling/ocio-env.sh links it STATICALLY when the package ships
|
|
# libOpenColorIO.a, dynamically otherwise (the DLL bundling step
|
|
# below then still applies).
|
|
tooling/ocio-env.sh >> "$GITHUB_ENV"
|
|
# ocio-sys' build.rs force-adds the MSVC + Windows SDK include
|
|
# dirs on Windows (meant for MSVC hosts); with the GNU toolchain
|
|
# that drags MSVC-only headers into the g++ compile. Unpack the
|
|
# crate and gate that block behind OCIO_RS_NO_MSVC_INCLUDES.
|
|
echo "OCIO_RS_NO_MSVC_INCLUDES=1" >> "$GITHUB_ENV"
|
|
CH=$(cygpath -u "${CARGO_HOME:-$HOME/.cargo}")
|
|
cargo fetch --locked
|
|
for cache in "$CH"/registry/cache/*/; do
|
|
src="$CH/registry/src/$(basename "$cache")"
|
|
mkdir -p "$src"
|
|
[ -f "$cache/ocio-sys-0.2.1.crate" ] && tar xzf "$cache/ocio-sys-0.2.1.crate" -C "$src"
|
|
done
|
|
BS=$(ls "$CH"/registry/src/*/ocio-sys-0.2.1/build.rs)
|
|
grep -q 'OCIO_RS_NO_MSVC_INCLUDES' "$BS" || sed -i \
|
|
's|if cfg!(target_os = "windows") && has_real_ocio {|if cfg!(target_os = "windows") \&\& has_real_ocio \&\& std::env::var_os("OCIO_RS_NO_MSVC_INCLUDES").is_none() {|' \
|
|
"$BS"
|
|
grep -q 'OCIO_RS_NO_MSVC_INCLUDES' "$BS"
|
|
|
|
# TEMP: cache disabled until the Gitea instance cache is provisioned (Cache cargo artifacts)
|
|
# uses: Swatinem/rust-cache@v2
|
|
# with:
|
|
# shared-key: oak-workspace
|
|
# cache-on-failure: true
|
|
|
|
# TEMP: cache disabled until the Gitea instance cache is provisioned (Cache project FFmpeg)
|
|
# uses: actions/cache@v4
|
|
# with:
|
|
# path: .cache/ffmpeg
|
|
# key: ffmpeg-${{ runner.os }}-${{ hashFiles('tooling/ffmpeg/build-ffmpeg.sh') }}
|
|
|
|
- name: Build project FFmpeg (static, GPL + free codecs + hwaccel)
|
|
run: |
|
|
bash tooling/ffmpeg/build-ffmpeg.sh
|
|
echo "FFMPEG_DIR=$(cygpath -m "$PWD/.cache/ffmpeg")" >> "$GITHUB_ENV"
|
|
|
|
- name: Install cargo-packager
|
|
run: cargo install cargo-packager --locked
|
|
|
|
- name: Generate app icon (PNG from Oak_Icon.svg)
|
|
run: |
|
|
mkdir -p icons
|
|
rsvg-convert -w 512 -h 512 Oak_Icon.svg -o icons/icon.png
|
|
|
|
- name: Build (release)
|
|
run: |
|
|
# Clear the job-hook-injected MSVC INCLUDE/LIB before the GNU
|
|
# build (they poison the MinGW compiles with MSVC SDK headers).
|
|
unset INCLUDE LIB
|
|
cargo build --release --locked
|
|
|
|
# Collect the MSYS2 runtime DLLs (libstdc++/libgcc/OpenColorIO/...)
|
|
# into target/pkg/win-dlls; the packager `resources` glob then
|
|
# installs them next to the executables.
|
|
- name: Bundle runtime DLLs
|
|
run: |
|
|
unset INCLUDE LIB
|
|
pacman -S --needed --noconfirm mingw-w64-ucrt-x86_64-ntldd
|
|
tooling/package/bundle-dylibs-windows.sh target/pkg/win-dlls \
|
|
target/release/oak-editor.exe target/release/oak-cli.exe \
|
|
target/release/oak-worker.exe
|
|
|
|
- name: Package (NSIS)
|
|
run: cargo packager --release --formats nsis
|
|
|
|
- name: Upload artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: oak-windows
|
|
path: target/release/*-setup.exe
|
|
if-no-files-found: error
|
|
|
|
# ------------------------------------------------------------------
|
|
# Publish: attach every platform package to the v* tag's GitHub release
|
|
# (skipped on workflow_dispatch, which only uploads artifacts).
|
|
# ------------------------------------------------------------------
|
|
release:
|
|
name: Publish GitHub release
|
|
needs: [linux, appimage, macos, windows]
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
runs-on: warp-ubuntu-latest-x64-8x
|
|
steps:
|
|
- name: Download all artifacts
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
path: artifacts
|
|
merge-multiple: true
|
|
|
|
- name: Publish release
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
tag_name: ${{ github.ref_name }}
|
|
name: ${{ github.ref_name }}
|
|
draft: false
|
|
files: artifacts/*
|
|
|