cd: container-native Linux packaging (deb/rpm/pacman) + AppImage
Each distro package builds inside that distro's container so declared dependencies always resolve to native names: hand-rolled deb via dpkg-shlibdeps + dpkg-deb, rpm via rpmbuild's auto-requires, Arch via makepkg (non-root builder user). git/curl install before checkout (container jobs). AppImage keeps cargo-packager on the Ubuntu runner. The release gates on all four package jobs plus macOS/Windows.
This commit is contained in:
+141
-87
@@ -16,8 +16,136 @@ jobs:
|
||||
# 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 (deb, AppImage, pacman)
|
||||
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
|
||||
;;
|
||||
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
|
||||
;;
|
||||
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
|
||||
;;
|
||||
esac
|
||||
|
||||
- name: Configure build environment
|
||||
run: |
|
||||
# OCIO builds from the ocio-sys vendored source (static) on
|
||||
# Linux; the distro packages are too old for the bridge.
|
||||
echo "OCIO_RS_ENABLE_REAL=1" >> "$GITHUB_ENV"
|
||||
echo "OCIO_RS_LINK=static" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Cache cargo artifacts
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
shared-key: oak-${{ matrix.distro }}
|
||||
|
||||
- name: 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
|
||||
VERSION="${GITHUB_REF_NAME#v}"
|
||||
if [ "$VERSION" = "$GITHUB_REF_NAME" ]; then
|
||||
VERSION="$(cargo pkgid | sed 's/.*#//' | cut -d@ -f2-)+git"
|
||||
fi
|
||||
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:
|
||||
@@ -32,41 +160,31 @@ jobs:
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
tooling/install-deps.sh
|
||||
# cmake/make for the vendored OpenColorIO build (ocio-sys
|
||||
# `bundled`; Ubuntu's libopencolorio-dev is older than the
|
||||
# bridge's API floor) + rsvg-convert for the app icon
|
||||
# (cargo-packager needs PNG/icns/ico, the repo only has
|
||||
# Oak_Icon.svg).
|
||||
sudo apt-get install -y \
|
||||
cmake \
|
||||
cmake librsvg2-bin \
|
||||
libpipewire-0.3-dev libspa-0.2-dev libjack-jackd2-dev \
|
||||
libasound2-dev libpulse-dev libsndfile1-dev \
|
||||
librsvg2-bin \
|
||||
libgl1-mesa-dev libgl1-mesa-dri mesa-vulkan-drivers \
|
||||
libvulkan-dev libxkbcommon-dev
|
||||
libvulkan-dev libxkbcommon-dev libxkbcommon-x11-dev
|
||||
|
||||
- name: Configure build environment
|
||||
run: |
|
||||
# No OCIO_INSTALL_DIR on purpose: the vendored OpenColorIO is
|
||||
# built from source (see ci.yml).
|
||||
echo "OCIO_RS_ENABLE_REAL=1" >> "$GITHUB_ENV"
|
||||
echo "OCIO_RS_LINK=static" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Cache cargo artifacts
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
shared-key: oak-workspace
|
||||
shared-key: oak-appimage
|
||||
|
||||
- name: Cache project FFmpeg
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .cache/ffmpeg
|
||||
key: ffmpeg-${{ runner.os }}-${{ hashFiles('tooling/ffmpeg/build-ffmpeg.sh') }}
|
||||
key: ffmpeg-appimage-${{ 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"
|
||||
run: tooling/ffmpeg/build-ffmpeg.sh
|
||||
|
||||
- name: Install cargo-packager
|
||||
run: cargo install cargo-packager --locked
|
||||
@@ -74,87 +192,22 @@ jobs:
|
||||
- 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
|
||||
|
||||
# Runtime-dependency audit: everything media-related (FFmpeg, OCIO)
|
||||
# is statically linked, so the NEEDED list should contain only
|
||||
# base-OS libraries (glibc, X11, ALSA/PipeWire, Vulkan) — names that
|
||||
# are stable across Debian/openKylin (no distro-specific package
|
||||
# names leak into the deb's dependency surface).
|
||||
- name: Audit runtime dependencies
|
||||
run: |
|
||||
for bin in target/release/oak-editor target/release/oak-cli target/release/oak-worker; do
|
||||
echo "== $bin"
|
||||
objdump -p "$bin" | grep NEEDED || true
|
||||
done
|
||||
- name: Package (AppImage)
|
||||
run: cargo packager --release --formats appimage
|
||||
|
||||
# Declare the FULL runtime dependency set on the deb. dpkg-shlibdeps
|
||||
# resolves every NEEDED entry of every shipped binary to the exact
|
||||
# package names of the build distro (FFmpeg/OCIO are statically
|
||||
# linked, so only base-OS packages appear); an empty Depends is not
|
||||
# self-containment, it just hides the requirements. Distros whose
|
||||
# package names differ (openKylin) get their own build so the names
|
||||
# always resolve.
|
||||
- name: Declare full dependencies on the deb
|
||||
run: |
|
||||
set -euo pipefail
|
||||
deps=$(for bin in target/release/oak-editor target/release/oak-cli target/release/oak-worker; do
|
||||
dpkg-shlibdeps -O "$bin"
|
||||
done | sed 's/^shlibs:Depends=//' | tr ',' '\n' | sed 's/^ //;s/ $//' | sort -u | paste -sd', ' -)
|
||||
echo "declared deps: $deps"
|
||||
for deb in target/release/*.deb; do
|
||||
rm -rf .deb-repack && mkdir .deb-repack
|
||||
dpkg-deb -R "$deb" .deb-repack
|
||||
if grep -q '^Depends:' .deb-repack/DEBIAN/control; then
|
||||
sed -i "s|^Depends:.*|Depends: $deps|" .deb-repack/DEBIAN/control
|
||||
else
|
||||
sed -i "1i Depends: $deps" .deb-repack/DEBIAN/control
|
||||
fi
|
||||
dpkg-deb -b .deb-repack "$deb"
|
||||
rm -rf .deb-repack
|
||||
done
|
||||
|
||||
|
||||
- name: Package (deb, AppImage, pacman)
|
||||
run: cargo packager --release --formats deb,appimage,pacman
|
||||
|
||||
# cargo-packager has no rpm format; convert the deb with fpm. The gem
|
||||
# bin dir may not be on PATH for the system ruby, so call fpm by path.
|
||||
- name: Package (rpm, via fpm)
|
||||
run: |
|
||||
sudo apt-get install -y ruby ruby-dev rpm
|
||||
sudo gem install --no-document fpm
|
||||
sudo "$(sudo gem env gemdir)/bin/fpm" -s deb -t rpm --name oak-editor \
|
||||
--version "$(cargo pkgid | sed 's/.*#//' | cut -d@ -f2-)" \
|
||||
target/release/*.deb
|
||||
mv ./*.rpm target/release/
|
||||
|
||||
- name: Upload artifacts
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: oak-linux
|
||||
path: |
|
||||
target/release/*.deb
|
||||
target/release/*.rpm
|
||||
target/release/*.AppImage
|
||||
target/release/*.tar.gz
|
||||
target/release/PKGBUILD
|
||||
name: oak-linux-appimage
|
||||
path: target/release/*.AppImage
|
||||
if-no-files-found: error
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# macOS: Apple Silicon only. The app/CLI/worker call the module rlibs
|
||||
# directly (oakengine is retired), so the .app bundle carries no dylib
|
||||
# to fold in; package it with cargo-packager and create the DMG with
|
||||
# hdiutil.
|
||||
# ------------------------------------------------------------------
|
||||
macos:
|
||||
name: macOS DMG (Apple Silicon)
|
||||
runs-on: warp-macos-15-arm64-6x
|
||||
@@ -337,7 +390,7 @@ jobs:
|
||||
# ------------------------------------------------------------------
|
||||
release:
|
||||
name: Publish GitHub release
|
||||
needs: [linux, macos, windows]
|
||||
needs: [linux, appimage, macos, windows]
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
runs-on: warp-ubuntu-latest-x64-8x
|
||||
steps:
|
||||
@@ -354,3 +407,4 @@ jobs:
|
||||
name: ${{ github.ref_name }}
|
||||
draft: false
|
||||
files: artifacts/*
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Oak Video Editor
|
||||
Comment=A free, open-source non-linear video editor
|
||||
Exec=oak-editor
|
||||
Icon=oak
|
||||
Categories=Video;AudioVideo;
|
||||
Terminal=false
|
||||
@@ -0,0 +1,40 @@
|
||||
# Oak Video Editor - Non-Linear Video Editor
|
||||
# Copyright (C) 2026 Oak Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Arch package build. The release binaries are built by the caller
|
||||
# (tooling/package/build-pkg.sh) before makepkg runs; depends lists the
|
||||
# base-OS packages the binaries link (FFmpeg/OCIO are statically linked).
|
||||
pkgname=oak-editor
|
||||
pkgver=@VERSION@
|
||||
pkgrel=1
|
||||
pkgdesc="Oak Video Editor — a free, open-source non-linear video editor"
|
||||
arch=('x86_64')
|
||||
url="https://github.com/OakVideoEditorCommunity/oak"
|
||||
license=('GPL-3.0-or-later')
|
||||
depends=('glibc' 'gcc-libs' 'alsa-lib' 'libpipewire' 'libx11' 'libxcb'
|
||||
'libxkbcommon' 'libxkbcommon-x11' 'libglvnd' 'vulkan-icd-loader'
|
||||
'fontconfig' 'freetype2')
|
||||
|
||||
package() {
|
||||
install -Dm755 "$OAK_BIN/oak-editor" "$pkgdir/usr/bin/oak-editor"
|
||||
install -Dm755 "$OAK_BIN/oak-cli" "$pkgdir/usr/bin/oak-cli"
|
||||
install -Dm755 "$OAK_BIN/oak-worker" "$pkgdir/usr/bin/oak-worker"
|
||||
install -Dm644 "$OAK_ROOT/packaging/oak.desktop" "$pkgdir/usr/share/applications/oak.desktop"
|
||||
install -Dm644 "$OAK_ROOT/icons/icon.png" "$pkgdir/usr/share/icons/hicolor/512x512/apps/oak.png"
|
||||
for f in "$OAK_ROOT"/assets/i18n/*.yaml; do
|
||||
install -Dm644 "$f" "$pkgdir/usr/share/oak/i18n/$(basename "$f")"
|
||||
done
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
# Oak Video Editor - Non-Linear Video Editor
|
||||
# Copyright (C) 2026 Oak Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# RPM spec for Oak. Requires are AUTO-COMPUTED by rpmbuild from the
|
||||
# packaged binaries' NEEDED entries (the distro's own names); do not add a
|
||||
# static Requires list.
|
||||
Name: oak-editor
|
||||
Version: %{_version}
|
||||
Release: 1%{?dist}
|
||||
Summary: Oak Video Editor — a free, open-source non-linear video editor
|
||||
License: GPL-3.0-or-later
|
||||
URL: https://github.com/OakVideoEditorCommunity/oak
|
||||
|
||||
%description
|
||||
Oak is a non-linear video editor written in Rust (OpenFX plug-in host,
|
||||
proxy editing, multicam, hardware decoding).
|
||||
|
||||
%install
|
||||
# Everything is staged into %{buildroot} by the caller (build-rpm.sh);
|
||||
# nothing to compile here.
|
||||
true
|
||||
|
||||
%files
|
||||
/usr/bin/oak-editor
|
||||
/usr/bin/oak-cli
|
||||
/usr/bin/oak-worker
|
||||
/usr/share/applications/oak.desktop
|
||||
/usr/share/icons/hicolor/512x512/apps/oak.png
|
||||
/usr/share/oak/i18n/
|
||||
|
||||
%changelog
|
||||
Reference in New Issue
Block a user