From 20b92ec2c5347c0e87e4f0512a1f0edd4017b118 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Tue, 6 Oct 2026 18:07:11 -0400 Subject: [PATCH] fix(ci): preserve Windows artifacts and correct macOS bundle layout --- .github/workflows/ci-windows-installer.yml | 13 +++++---- crates/server/src/config.rs | 32 ++++++++++++++++++---- packaging/macos/package-dmg.sh | 9 ++++-- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci-windows-installer.yml b/.github/workflows/ci-windows-installer.yml index 3b923b4..7e289b4 100644 --- a/.github/workflows/ci-windows-installer.yml +++ b/.github/workflows/ci-windows-installer.yml @@ -59,12 +59,6 @@ jobs: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Download Windows build artifact - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: build-windows-${{ matrix.target }} - path: . - - name: Setup Rust uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0 with: @@ -90,6 +84,13 @@ jobs: cargo update --workspace cargo metadata --locked --no-deps --format-version 1 > $null + # Rust cache restoration can clean target files on a partial cache hit. + - name: Download Windows build artifact + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: build-windows-${{ matrix.target }} + path: . + - name: Setup dotnet uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: diff --git a/crates/server/src/config.rs b/crates/server/src/config.rs index 7cbfb33..c3c6c5f 100644 --- a/crates/server/src/config.rs +++ b/crates/server/src/config.rs @@ -171,11 +171,16 @@ fn media_tool_path_in( directory: &std::path::Path, name: &str, ) -> String { - let binary = directory - .join("ffmpeg") - .join("bin") - .join(format!("{name}{}", std::env::consts::EXE_SUFFIX)); - if binary.is_file() { binary.to_string_lossy().into_owned() } else { name.to_owned() } + let filename = format!("{name}{}", std::env::consts::EXE_SUFFIX); + // macOS app bundles keep helper executables directly in Contents/MacOS. + [ + directory.join("ffmpeg").join("bin").join(&filename), + directory.join(&filename), + ] + .into_iter() + .find(|binary| binary.is_file()) + .map(|binary| binary.to_string_lossy().into_owned()) + .unwrap_or_else(|| name.to_owned()) } #[cfg(test)] @@ -214,6 +219,23 @@ mod bundled_media_tool_tests { std::fs::remove_dir_all(directory).unwrap(); } + #[test] + fn resolves_tools_in_macos_bundle_layout() { + let root = + std::env::temp_dir().join(format!("koko-macos-media-tools-{}", std::process::id())); + let directory = root.join("Koko.app").join("Contents").join("MacOS"); + std::fs::create_dir_all(&directory).unwrap(); + for name in ["ffmpeg", "ffprobe"] { + let binary = directory.join(format!("{name}{}", std::env::consts::EXE_SUFFIX)); + std::fs::write(&binary, b"fixture").unwrap(); + assert_eq!( + media_tool_path_in(&directory, name), + binary.to_string_lossy() + ); + } + std::fs::remove_dir_all(root).unwrap(); + } + fn in_memory_database() -> diesel::SqliteConnection { use diesel::Connection; let mut connection = diesel::SqliteConnection::establish(":memory:").unwrap(); diff --git a/packaging/macos/package-dmg.sh b/packaging/macos/package-dmg.sh index 7728d49..eddfe12 100644 --- a/packaging/macos/package-dmg.sh +++ b/packaging/macos/package-dmg.sh @@ -137,7 +137,12 @@ rm -rf "${package_dir}" mkdir -p "${macos_dir}" "${resources_dir}" "${dmg_root}" "${output_dir}" install -m 0755 "${binary_path}" "${macos_dir}/koko" -ditto "$(dirname "${binary_path}")/ffmpeg" "${macos_dir}/ffmpeg" +ffmpeg_dir="$(dirname "${binary_path}")/ffmpeg" +for tool in ffmpeg ffprobe; do + install -m 0755 "${ffmpeg_dir}/bin/${tool}" "${macos_dir}/${tool}" +done +# Code belongs in MacOS; license files must be sealed as resources. +ditto "${ffmpeg_dir}/share" "${resources_dir}/ffmpeg/share" ditto "assets" "${resources_dir}/assets" ditto "crates/client-web/dist" "${resources_dir}/client-web/dist" install -m 0644 "LICENSE" "${resources_dir}/LICENSE" @@ -196,7 +201,7 @@ if [[ "${sign_bundle}" == "true" ]]; then xattr -rc "${app_dir}" for tool in ffmpeg ffprobe; do codesign --force --timestamp --options runtime \ - --sign "${codesign_identity}" "${macos_dir}/ffmpeg/bin/${tool}" + --sign "${codesign_identity}" "${macos_dir}/${tool}" done codesign --force --timestamp --options runtime \ --sign "${codesign_identity}" \