A cold vcpkg FFmpeg build costs ~40 minutes per Windows run and the Windows dependency chain is the hardest to keep healthy; BtbN's builds come from public GitHub Actions on the release/8.1 branch (BtbN is an FFmpeg developer; ffmpeg.org links these builds as the official Windows option). The archive ships include/, MSVC import libs (.lib), pkg-config files and the runtime DLLs, and is fetched straight from his release page with the checksums.sha256 published in the same release — nothing is mirrored here, so provenance stays upstream. The Windows jobs download/verify/extract it to .cache/ffmpeg (the checksum comes from that release's own checksums.sha256), point FFMPEG_DIR/PKG_CONFIG_PATH at it (pkgconf still comes from vcpkg) and the installer bundles its DLLs. The manifest gates ffmpeg to !windows and drops librsvg (the icon now ships as the committed PNG).
537 lines
24 KiB
YAML
537 lines
24 KiB
YAML
name: CD
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*'
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
# One matrix, seven platforms, the same environments CI tests in (see
|
|
# .github/workflows/ci.yml): Debian 12 / Fedora 43 / Arch / openKylin x64
|
|
# and arm64 containers plus the macOS and Windows hosts. Every package is
|
|
# built from scratch — no vcpkg/cargo caches: a restored vcpkg_installed
|
|
# or target tree has masked packaging problems before (stale ports,
|
|
# missing tools), and a release must not depend on restored state.
|
|
jobs:
|
|
package:
|
|
name: Package (${{ matrix.name }})
|
|
runs-on: ${{ matrix.runner }}
|
|
# Container entries carry the container as JSON ({"image":...,
|
|
# "options":...}); the empty string means "run on the host"
|
|
# (actions/runner#265 allows an empty container value).
|
|
container: ${{ matrix.container != '' && fromJSON(matrix.container) || '' }}
|
|
# Cold vcpkg install + release build + packaging.
|
|
timeout-minutes: 150
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- name: Debian
|
|
platform: linux
|
|
distro: debian
|
|
arch: x64
|
|
runner: warp-ubuntu-latest-x64-32x
|
|
triplet: x64-linux
|
|
artifact: linux-debian
|
|
container: '{"image":"debian:12","options":"--shm-size=8g"}'
|
|
- name: Fedora
|
|
platform: linux
|
|
distro: fedora
|
|
arch: x64
|
|
runner: warp-ubuntu-latest-x64-32x
|
|
triplet: x64-linux
|
|
artifact: linux-fedora
|
|
container: '{"image":"fedora:43","options":"--shm-size=8g"}'
|
|
- name: Arch
|
|
platform: linux
|
|
distro: arch
|
|
arch: x64
|
|
runner: warp-ubuntu-latest-x64-32x
|
|
triplet: x64-linux
|
|
artifact: linux-arch
|
|
container: '{"image":"archlinux:latest","options":"--shm-size=8g"}'
|
|
- name: openKylin x64
|
|
platform: linux
|
|
distro: openkylin
|
|
arch: x64
|
|
runner: warp-ubuntu-latest-x64-32x
|
|
triplet: x64-linux
|
|
artifact: linux-openkylin-x64
|
|
container: '{"image":"openkylin/openkylin:latest","options":"--shm-size=8g"}'
|
|
- name: openKylin arm64
|
|
platform: linux
|
|
distro: openkylin
|
|
arch: arm64
|
|
runner: warp-ubuntu-latest-arm64-32x
|
|
triplet: arm64-linux
|
|
artifact: linux-openkylin-arm64
|
|
container: '{"image":"openkylin/openkylin:latest","options":"--shm-size=8g"}'
|
|
- name: macOS
|
|
platform: macos
|
|
distro: macos
|
|
arch: arm64
|
|
runner: warp-macos-26-arm64-12x
|
|
triplet: arm64-osx
|
|
artifact: macos
|
|
container: ''
|
|
- name: Windows
|
|
platform: windows
|
|
distro: windows
|
|
arch: x64
|
|
runner: warp-windows-2025-vs2026-x64-32x
|
|
triplet: x64-windows
|
|
artifact: windows
|
|
container: ''
|
|
|
|
steps:
|
|
# The container images are bare (Fedora/Arch even lack git);
|
|
# checkout and vcpkg need git/curl. First step of the job, so the
|
|
# package lists are still fresh.
|
|
- name: Bootstrap container (git, curl, wget)
|
|
if: matrix.container != ''
|
|
shell: bash
|
|
run: |
|
|
case "${{ matrix.distro }}" in
|
|
fedora) dnf install -y --setopt=install_weak_deps=False --setopt=max_parallel_downloads=16 git curl wget which ;;
|
|
arch) pacman -Sy --noconfirm git curl wget which ;;
|
|
debian|openkylin) apt-get update && apt-get install -y git curl ca-certificates wget ;;
|
|
esac
|
|
|
|
- name: Checkout
|
|
uses: actions/checkout@v7
|
|
with:
|
|
# gpui/ is a git submodule; its crates are workspace members of
|
|
# their own repo and build as path dependencies of oakapp.
|
|
submodules: true
|
|
|
|
# Defender's real-time scanning slows the MSVC/vcpkg build down
|
|
# badly; disable it for the job and keep exclusions as the fallback
|
|
# when policy blocks the change.
|
|
- name: Disable Windows Defender scanning
|
|
if: matrix.platform == 'windows'
|
|
shell: pwsh
|
|
run: |
|
|
try {
|
|
Set-MpPreference -DisableRealtimeMonitoring $true -ErrorAction Stop
|
|
Set-MpPreference -DisableScriptScanning $true -ErrorAction SilentlyContinue
|
|
Set-MpPreference -DisableArchiveScanning $true -ErrorAction SilentlyContinue
|
|
Write-Host "Windows Defender real-time scanning disabled for this job"
|
|
} catch {
|
|
Write-Host "Windows Defender could not be disabled (non-fatal, falling back to exclusions): $_"
|
|
}
|
|
foreach ($path in @(
|
|
$env:GITHUB_WORKSPACE,
|
|
"$env:USERPROFILE\.cargo",
|
|
"$env:USERPROFILE\.rustup",
|
|
"$env:LOCALAPPDATA\vcpkg"
|
|
)) {
|
|
Add-MpPreference -ExclusionPath $path -ErrorAction SilentlyContinue
|
|
}
|
|
try {
|
|
Get-MpPreference |
|
|
Select-Object DisableRealtimeMonitoring, DisableScriptScanning, ExclusionPath |
|
|
Format-List
|
|
} catch {
|
|
Write-Host "Defender status unavailable: $_"
|
|
}
|
|
|
|
# The containers run as root but Actions sets HOME=/github/home;
|
|
# rustup refuses the euid mismatch ("$HOME differs from
|
|
# euid-obtained home directory") and would install a toolchain the
|
|
# later steps cannot find under the Actions home. Pin the job to
|
|
# root's home so rustup/cargo and the toolchain agree.
|
|
- name: Pin HOME for rustup
|
|
if: matrix.container != ''
|
|
shell: bash
|
|
run: |
|
|
{
|
|
echo "HOME=/root"
|
|
echo "CARGO_HOME=/root/.cargo"
|
|
echo "RUSTUP_HOME=/root/.rustup"
|
|
} >> "$GITHUB_ENV"
|
|
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
# The Windows build is MSVC-ABI (the runner carries VS 2026):
|
|
# vcpkg's FFmpeg and the vendored OCIO build both want it.
|
|
toolchain: ${{ matrix.platform == 'windows' && 'stable-x86_64-pc-windows-msvc' || 'stable' }}
|
|
|
|
# ------------------------------------------------------------------
|
|
# System dependencies — one list per distro, byte-for-byte the same
|
|
# lists CI uses (see .github/workflows/ci.yml): what compiles there
|
|
# compiles here.
|
|
# ------------------------------------------------------------------
|
|
- name: Install system dependencies (Debian)
|
|
if: matrix.distro == 'debian'
|
|
shell: bash
|
|
run: |
|
|
apt-get update
|
|
apt-get install -y \
|
|
build-essential clang libclang-dev cmake pkg-config nasm \
|
|
git curl zip unzip tar python3 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 xvfb libdrm-dev \
|
|
icc-profiles-free gdb file librsvg2-bin patchelf \
|
|
autoconf autoconf-archive automake libtool
|
|
|
|
- name: Install system dependencies (Fedora)
|
|
if: matrix.distro == 'fedora'
|
|
shell: bash
|
|
run: |
|
|
# Fedora 41 is EOL (its mirrors moved to the slow archive), so
|
|
# the matrix uses the current release; weak dependencies (docs,
|
|
# fonts, optional tooling) are skipped and downloads run wide.
|
|
dnf install -y --setopt=install_weak_deps=False \
|
|
--setopt=max_parallel_downloads=16 \
|
|
gcc gcc-c++ clang clang-devel cmake pkgconf-pkg-config nasm \
|
|
git curl zip unzip tar python3 patch xz which \
|
|
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 libdrm-devel \
|
|
perl-IPC-Cmd perl-FindBin perl-File-Basename perl-File-Compare \
|
|
perl-File-Copy perl-File-Path perl-File-Temp perl-Time-Piece \
|
|
xorg-x11-server-Xvfb xorg-x11-xauth gdb file \
|
|
autoconf autoconf-archive automake libtool
|
|
|
|
- name: Install system dependencies (Arch)
|
|
if: matrix.distro == 'arch'
|
|
shell: bash
|
|
run: |
|
|
pacman -S --needed --noconfirm \
|
|
base-devel clang cmake pkgconf nasm \
|
|
git curl zip unzip tar python patch xz which \
|
|
pipewire jack2 alsa-lib libpulse libsndfile \
|
|
mesa vulkan-headers vulkan-icd-loader \
|
|
libxkbcommon libxkbcommon-x11 librsvg libdrm \
|
|
xorg-server-xvfb xorg-xauth gdb file \
|
|
autoconf autoconf-archive automake libtool
|
|
|
|
- name: Install system dependencies (openKylin)
|
|
if: matrix.distro == 'openkylin'
|
|
shell: bash
|
|
run: |
|
|
apt-get update
|
|
apt-get install -y \
|
|
build-essential clang libclang-dev cmake pkg-config nasm \
|
|
git curl zip unzip tar python3 patch xz-utils 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 xvfb libdrm-dev \
|
|
gdb file patchelf fonts-dejavu-core \
|
|
autoconf autoconf-archive automake libtool
|
|
|
|
- name: Install system dependencies (macOS)
|
|
if: matrix.platform == 'macos'
|
|
run: |
|
|
# Homebrew's pkgconf installs a `pkg-config` symlink, which is
|
|
# the name crates/oak-ffmpeg-link/build.rs invokes; nasm is what
|
|
# vcpkg's ffmpeg port requires to build (FFmpeg libraries come
|
|
# from the vcpkg manifest). librsvg stays for rsvg-convert (app
|
|
# icon) and is bundled into the .app by the dylib script.
|
|
brew install cmake pkg-config nasm librsvg autoconf automake libtool autoconf-archive
|
|
|
|
# Windows uses BtbN's prebuilt FFmpeg (GPL, shared): the archive
|
|
# ships include/, MSVC import libs (.lib), pkg-config files and the
|
|
# runtime DLLs, built from FFmpeg's release/8.1 branch by BtbN's
|
|
# public GitHub Actions (BtbN is an FFmpeg developer and ffmpeg.org
|
|
# links these builds). Downloaded from his release page and
|
|
# verified against the checksums.sha256 published in the same
|
|
# release; nothing is mirrored here, so provenance stays upstream.
|
|
# The alternative — a cold vcpkg FFmpeg build — costs ~40 minutes
|
|
# per run on this platform.
|
|
- name: Install prebuilt FFmpeg (Windows)
|
|
if: matrix.platform == 'windows'
|
|
shell: pwsh
|
|
run: |
|
|
$base = "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest"
|
|
$asset = "ffmpeg-n8.1-latest-win64-gpl-shared-8.1.zip"
|
|
$dir = Join-Path $env:RUNNER_TEMP "ffmpeg-prebuilt"
|
|
New-Item -ItemType Directory -Force $dir | Out-Null
|
|
Invoke-WebRequest -Uri "$base/checksums.sha256" -OutFile "$dir\checksums.sha256"
|
|
$line = Select-String -Path "$dir\checksums.sha256" -Pattern ([regex]::Escape($asset) + "\s*$") |
|
|
Select-Object -First 1
|
|
if (-not $line) { throw "no checksum for $asset in the release's checksums.sha256" }
|
|
$expected = $line.Line.Split()[0].ToLowerInvariant()
|
|
Invoke-WebRequest -Uri "$base/$asset" -OutFile "$dir\$asset"
|
|
$actual = (Get-FileHash "$dir\$asset" -Algorithm SHA256).Hash.ToLowerInvariant()
|
|
if ($actual -ne $expected) { throw "FFmpeg checksum mismatch: expected $expected, got $actual" }
|
|
$root = "$env:GITHUB_WORKSPACE\.cache"
|
|
Remove-Item "$root\ffmpeg", "$root\ffmpeg-extract" -Recurse -Force -ErrorAction SilentlyContinue
|
|
Expand-Archive -Path "$dir\$asset" -DestinationPath "$root\ffmpeg-extract" -Force
|
|
$inner = Get-ChildItem "$root\ffmpeg-extract" -Directory | Select-Object -First 1
|
|
Move-Item $inner.FullName "$root\ffmpeg"
|
|
|
|
# ------------------------------------------------------------------
|
|
# vcpkg (manifest mode) — built from scratch, no caches
|
|
# ------------------------------------------------------------------
|
|
# Bootstrap a fresh clone rather than leaning on whatever vcpkg the
|
|
# image carries: `builtin-baseline`/`overrides` are only honored by
|
|
# a recent vcpkg-tool, and every platform must behave alike.
|
|
- name: Bootstrap vcpkg
|
|
if: matrix.platform != 'windows'
|
|
shell: bash
|
|
run: |
|
|
git clone https://github.com/microsoft/vcpkg.git .cache/vcpkg
|
|
.cache/vcpkg/bootstrap-vcpkg.sh -disableMetrics
|
|
echo "$PWD/.cache/vcpkg" >> "$GITHUB_PATH"
|
|
echo "VCPKG_ROOT=$PWD/.cache/vcpkg" >> "$GITHUB_ENV"
|
|
|
|
- name: Bootstrap vcpkg (Windows)
|
|
if: matrix.platform == 'windows'
|
|
shell: pwsh
|
|
run: |
|
|
git clone https://github.com/microsoft/vcpkg.git "$env:GITHUB_WORKSPACE\.cache\vcpkg"
|
|
& "$env:GITHUB_WORKSPACE\.cache\vcpkg\bootstrap-vcpkg.bat" -disableMetrics
|
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
|
"$env:GITHUB_WORKSPACE\.cache\vcpkg" >> $env:GITHUB_PATH
|
|
"VCPKG_ROOT=$env:GITHUB_WORKSPACE\.cache\vcpkg" >> $env:GITHUB_ENV
|
|
|
|
- name: Install dependencies (vcpkg manifest)
|
|
if: matrix.platform != 'windows'
|
|
shell: bash
|
|
run: |
|
|
# Source tarballs come from third-party hosts (x264 lives on
|
|
# code.videolan.org); a transient connection failure aborts the
|
|
# whole install — vcpkg refuses to retry that class of curl
|
|
# error — so retry here.
|
|
for attempt in 1 2 3; do
|
|
vcpkg install --triplet ${{ matrix.triplet }} --overlay-triplets tooling/vcpkg-triplets/release --overlay-ports tooling/vcpkg-ports && exit 0
|
|
echo "vcpkg install failed (attempt $attempt); retrying"
|
|
sleep 15
|
|
done
|
|
exit 1
|
|
|
|
- name: Install dependencies (vcpkg manifest, Windows)
|
|
if: matrix.platform == 'windows'
|
|
shell: pwsh
|
|
run: |
|
|
for ($i = 1; $i -le 3; $i++) {
|
|
vcpkg install --triplet ${{ matrix.triplet }} --overlay-triplets tooling/vcpkg-triplets/release --overlay-ports tooling/vcpkg-ports
|
|
if ($LASTEXITCODE -eq 0) { exit 0 }
|
|
Write-Host "vcpkg install failed (attempt $i); retrying"
|
|
Start-Sleep -Seconds 15
|
|
}
|
|
exit 1
|
|
|
|
# ------------------------------------------------------------------
|
|
# Build environment
|
|
# ------------------------------------------------------------------
|
|
# ocio-sys builds a stub bridge unless these are set; the oak-core
|
|
# ocioutils tests need the real library.
|
|
# tooling/ocio-env.sh: vendored static OCIO (the [patch.crates-io]
|
|
# ocio-sys tracks shaloong/ocio-rs main, whose vendored sources build
|
|
# on GCC >= 16).
|
|
- name: Configure build environment (Linux)
|
|
if: matrix.platform == 'linux'
|
|
shell: bash
|
|
run: |
|
|
{
|
|
echo "CC=clang"
|
|
echo "CXX=clang++"
|
|
} >> "$GITHUB_ENV"
|
|
bash tooling/ocio-env.sh >> "$GITHUB_ENV"
|
|
prefix="$PWD/vcpkg_installed/${{ matrix.triplet }}"
|
|
echo "FFMPEG_DIR=$prefix" >> "$GITHUB_ENV"
|
|
echo "PKG_CONFIG_PATH=$prefix/lib/pkgconfig" >> "$GITHUB_ENV"
|
|
echo "$prefix/tools/pkgconf" >> "$GITHUB_PATH"
|
|
echo "LD_LIBRARY_PATH=$prefix/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" >> "$GITHUB_ENV"
|
|
# The Debian-family packaging tools resolve the ELF needs through
|
|
# ldd (dpkg-shlibdeps, linuxdeploy): register the vcpkg libs with
|
|
# the dynamic linker so `libva-drm.so.2` is found when a package
|
|
# is assembled.
|
|
echo "$prefix/lib" > /etc/ld.so.conf.d/oak-vcpkg.conf
|
|
ldconfig
|
|
|
|
- name: Configure build environment (macOS)
|
|
if: matrix.platform == 'macos'
|
|
shell: bash
|
|
run: |
|
|
# Vendored static OCIO (same as every non-Windows platform via
|
|
# tooling/ocio-env.sh); no OCIO_INSTALL_DIR override.
|
|
bash tooling/ocio-env.sh >> "$GITHUB_ENV"
|
|
prefix="$PWD/vcpkg_installed/${{ matrix.triplet }}"
|
|
echo "FFMPEG_DIR=$prefix" >> "$GITHUB_ENV"
|
|
echo "PKG_CONFIG_PATH=$prefix/lib/pkgconfig" >> "$GITHUB_ENV"
|
|
echo "$prefix/tools/pkgconf" >> "$GITHUB_PATH"
|
|
|
|
- name: Configure build environment (Windows)
|
|
if: matrix.platform == 'windows'
|
|
shell: pwsh
|
|
run: |
|
|
# FFmpeg comes from the prebuilt archive extracted above (the
|
|
# manifest no longer installs it on Windows); vcpkg only
|
|
# provides pkgconf for oak-ffmpeg-link's build script.
|
|
$prefix = "$env:GITHUB_WORKSPACE\vcpkg_installed\${{ matrix.triplet }}"
|
|
$ffmpeg = "$env:GITHUB_WORKSPACE\.cache\ffmpeg"
|
|
"FFMPEG_DIR=$ffmpeg" >> $env:GITHUB_ENV
|
|
"PKG_CONFIG_PATH=$ffmpeg\lib\pkgconfig" >> $env:GITHUB_ENV
|
|
"$ffmpeg\bin" >> $env:GITHUB_PATH
|
|
"$prefix\tools\pkgconf" >> $env:GITHUB_PATH
|
|
# Bundled OCIO: ocio-sys' vendored sources build with the MSVC
|
|
# toolchain (what they need — the MSYS2 package was the
|
|
# workaround, not the preference), so no OCIO_INSTALL_DIR and
|
|
# no OCIO_RS_NO_MSVC_INCLUDES anywhere.
|
|
"OCIO_RS_ENABLE_REAL=1" >> $env:GITHUB_ENV
|
|
"OCIO_RS_LINK=static" >> $env:GITHUB_ENV
|
|
vcpkg list
|
|
|
|
- name: Install cargo-packager
|
|
if: matrix.distro == 'debian' || matrix.platform != 'linux'
|
|
run: cargo install cargo-packager --locked
|
|
|
|
- name: Generate app icon (PNG from Oak_Icon.svg)
|
|
if: matrix.platform != 'windows'
|
|
run: |
|
|
mkdir -p icons
|
|
if command -v rsvg-convert >/dev/null 2>&1; then
|
|
rsvg-convert -w 512 -h 512 Oak_Icon.svg -o icons/icon.png
|
|
else
|
|
# Defensive: some containers may not carry an SVG renderer;
|
|
# fall back to the committed 512x512 render.
|
|
cp assets/app-icon.png icons/icon.png
|
|
fi
|
|
|
|
# ------------------------------------------------------------------
|
|
# Build
|
|
# ------------------------------------------------------------------
|
|
# Default dynamic CRT on Windows: the vendored OCIO is compiled /MD,
|
|
# so forcing Rust to /MT fails with LNK2038 'RuntimeLibrary'
|
|
# mismatch; the redistributable DLLs ship with the installer below.
|
|
- name: Build (release)
|
|
run: cargo build --release --locked
|
|
|
|
# ------------------------------------------------------------------
|
|
# Package
|
|
# ------------------------------------------------------------------
|
|
- name: Package (Linux)
|
|
if: matrix.platform == 'linux'
|
|
shell: bash
|
|
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)
|
|
# The general Debian-family package, labeled "+debian".
|
|
VCPKG_LIB="$PWD/vcpkg_installed/${{ matrix.triplet }}/lib" \
|
|
tooling/package/build-deb.sh "$VERSION" debian
|
|
# appimagetool self-extracts instead of mounting (containers
|
|
# have no FUSE).
|
|
APPIMAGE_EXTRACT_AND_RUN=1 cargo packager --release --formats appimage
|
|
;;
|
|
fedora)
|
|
tooling/package/build-rpm.sh "$VERSION"
|
|
;;
|
|
arch)
|
|
tooling/package/build-pkg.sh "$VERSION"
|
|
;;
|
|
openkylin)
|
|
# The openKylin build, labeled "+openkylin"; dpkg-shlibdeps
|
|
# resolves the runtime deps against openKylin's own repos
|
|
# and the vcpkg libva/libdrm ship next to the app (openKylin's
|
|
# system libva predates FFmpeg's vaMapBuffer2).
|
|
VCPKG_LIB="$PWD/vcpkg_installed/${{ matrix.triplet }}/lib" \
|
|
tooling/package/build-deb.sh "$VERSION" openkylin
|
|
;;
|
|
esac
|
|
|
|
- name: Package (macOS)
|
|
if: matrix.platform == 'macos'
|
|
run: |
|
|
cargo packager --release --formats app
|
|
# cargo-packager names the bundle after the packager
|
|
# `productName` ("Oak Video Editor.app"), so resolve it instead
|
|
# of guessing.
|
|
APP="$(ls -d target/release/*.app | head -1)"
|
|
tooling/package/bundle-dylibs-macos.sh "$APP"
|
|
rm -rf dmg-staging
|
|
mkdir -p dmg-staging
|
|
cp -R "$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: Bundle runtime DLLs
|
|
if: matrix.platform == 'windows'
|
|
shell: pwsh
|
|
run: |
|
|
New-Item -ItemType Directory -Force target/pkg/win-dlls | Out-Null
|
|
# FFmpeg + codec DLLs from the prebuilt archive (see above).
|
|
Copy-Item "$env:GITHUB_WORKSPACE\.cache\ffmpeg\bin\*.dll" target/pkg/win-dlls/
|
|
# The MSVC runtime: the build keeps the default dynamic CRT (see
|
|
# the Build step), so ship the redistributable DLLs app-locally.
|
|
$crt = Get-ChildItem "$env:ProgramFiles\Microsoft Visual Studio\*\*\VC\Redist\MSVC\*\x64\Microsoft.VC*.CRT" -Directory -ErrorAction SilentlyContinue |
|
|
Sort-Object FullName | Select-Object -Last 1
|
|
if (-not $crt) { throw "MSVC CRT redist directory not found" }
|
|
Copy-Item "$($crt.FullName)\*.dll" target/pkg/win-dlls/
|
|
|
|
- name: Package (NSIS)
|
|
if: matrix.platform == 'windows'
|
|
shell: pwsh
|
|
run: cargo packager --release --formats nsis
|
|
|
|
# ------------------------------------------------------------------
|
|
# Upload
|
|
# ------------------------------------------------------------------
|
|
- name: Stage artifacts
|
|
if: matrix.platform != 'windows'
|
|
shell: bash
|
|
run: |
|
|
mkdir -p dist
|
|
cp target/release/*.deb dist/ 2>/dev/null || true
|
|
cp target/release/*.rpm dist/ 2>/dev/null || true
|
|
cp target/release/*.pkg.tar.zst dist/ 2>/dev/null || true
|
|
cp target/release/*.AppImage dist/ 2>/dev/null || true
|
|
cp ./*.dmg dist/ 2>/dev/null || true
|
|
ls -la dist
|
|
|
|
- name: Stage artifacts (Windows)
|
|
if: matrix.platform == 'windows'
|
|
shell: pwsh
|
|
run: |
|
|
New-Item -ItemType Directory -Force dist | Out-Null
|
|
Copy-Item target/release/*-setup.exe dist/
|
|
Get-ChildItem dist
|
|
|
|
- name: Upload artifact
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: oak-${{ matrix.artifact }}
|
|
path: dist/*
|
|
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: [package]
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
runs-on: warp-ubuntu-latest-x64-32x
|
|
steps:
|
|
- name: Download all artifacts
|
|
uses: actions/download-artifact@v8
|
|
with:
|
|
path: artifacts
|
|
merge-multiple: true
|
|
|
|
- name: Publish release
|
|
uses: softprops/action-gh-release@v3
|
|
with:
|
|
tag_name: ${{ github.ref_name }}
|
|
name: ${{ github.ref_name }}
|
|
draft: false
|
|
files: artifacts/*
|