Some checks failed
Tagged release / prepare-release (push) Successful in 3m0s
Tagged release / build-linux-x64 (push) Failing after 28m43s
Tagged release / build-macos (push) Has been skipped
Tagged release / build-linux-arm64 (push) Has been skipped
Tagged release / build-windows (push) Has been skipped
Tagged release / publish-release (push) Has been skipped
262 lines
11 KiB
Rust
262 lines
11 KiB
Rust
use std::{fs, path::Path};
|
|
|
|
const CRATE_DIR: &str = env!("CARGO_MANIFEST_DIR");
|
|
|
|
#[test]
|
|
fn desktop_packages_have_native_icons_and_cargo_commands() {
|
|
let assets = Path::new(CRATE_DIR).join("assets/app-icons");
|
|
let png = fs::read(assets.join("bds.png")).expect("Linux PNG icon");
|
|
let ico = fs::read(assets.join("bds.ico")).expect("Windows ICO icon");
|
|
let icns = fs::read(assets.join("bds.icns")).expect("macOS ICNS icon");
|
|
|
|
assert_eq!(&png[..8], b"\x89PNG\r\n\x1a\n");
|
|
assert_eq!(u32::from_be_bytes(png[16..20].try_into().unwrap()), 1024);
|
|
assert_eq!(u32::from_be_bytes(png[20..24].try_into().unwrap()), 1024);
|
|
assert_eq!(&ico[..4], &[0, 0, 1, 0]);
|
|
assert!(u16::from_le_bytes(ico[4..6].try_into().unwrap()) >= 6);
|
|
assert_eq!(&icns[..4], b"icns");
|
|
|
|
let manifest = fs::read_to_string(Path::new(CRATE_DIR).join("Cargo.toml")).unwrap();
|
|
for required in [
|
|
"[package.metadata.packager]",
|
|
"assets/app-icons/bds.png",
|
|
"assets/app-icons/bds.ico",
|
|
"assets/app-icons/bds.icns",
|
|
"identifier = \"de.rfc1437.ruds\"",
|
|
"deep-link-protocols = [{ schemes = [\"ruds\"] }]",
|
|
"minimum-system-version = \"26.0\"",
|
|
"[package.metadata.packager.deb]",
|
|
"libgtk-3-0t64 | libgtk-3-0",
|
|
"libwebkit2gtk-4.1-0",
|
|
"libxdo3",
|
|
"../../target/release/bds-runtime/*",
|
|
"cargo run --quiet -p bds-package-runtime",
|
|
"cargo run --quiet -p bds-package-runtime -- sign-app-for-dmg",
|
|
"{ path = \"bds-mcp\" }",
|
|
] {
|
|
assert!(manifest.contains(required), "missing {required}");
|
|
}
|
|
assert!(!manifest.contains("signing-identity"));
|
|
assert!(manifest.contains("authors.workspace = true"));
|
|
|
|
let cargo_config = fs::read_to_string(Path::new(CRATE_DIR).join("../../.cargo/config.toml"))
|
|
.expect("Cargo packaging aliases");
|
|
for alias in ["bundle-macos", "bundle-windows", "bundle-linux"] {
|
|
assert!(cargo_config.contains(alias), "missing cargo {alias}");
|
|
}
|
|
assert!(cargo_config.contains("prefer-dynamic"));
|
|
assert!(cargo_config.contains("-mmacosx-version-min=26.0"));
|
|
assert!(cargo_config.contains("@executable_path/../Resources"));
|
|
assert!(cargo_config.contains("$ORIGIN:$ORIGIN/../lib/bds-ui"));
|
|
|
|
let main = fs::read_to_string(Path::new(CRATE_DIR).join("src/main.rs")).unwrap();
|
|
assert!(main.contains("assets/app-icons/bds.png"));
|
|
|
|
let build = fs::read_to_string(Path::new(CRATE_DIR).join("build.rs")).unwrap();
|
|
assert!(build.contains("set_icon(\"assets/app-icons/bds.ico\")"));
|
|
|
|
let workspace_manifest =
|
|
fs::read_to_string(Path::new(CRATE_DIR).join("../../Cargo.toml")).unwrap();
|
|
assert!(workspace_manifest.contains("Georg Bauer <gb@rfc1437.de>"));
|
|
assert!(workspace_manifest.contains("strip = \"symbols\""));
|
|
assert!(workspace_manifest.contains("ort-download-binaries-rustls-tls"));
|
|
assert!(workspace_manifest.contains("\"copy-dylibs\""));
|
|
assert!(workspace_manifest.contains("\"sync-secret-service\", \"vendored\""));
|
|
assert!(
|
|
workspace_manifest
|
|
.contains("libwebp-sys = { version = \"0.9.6\", default-features = false }")
|
|
);
|
|
|
|
let core_manifest =
|
|
fs::read_to_string(Path::new(CRATE_DIR).join("../bds-core/Cargo.toml")).unwrap();
|
|
assert!(core_manifest.contains("crate-type = [\"dylib\"]"));
|
|
assert!(core_manifest.contains("[target.'cfg(target_os = \"windows\")'.dependencies]"));
|
|
assert!(core_manifest.contains("libwebp-sys = { workspace = true, features = [\"sse41\"] }"));
|
|
let core_build = fs::read_to_string(Path::new(CRATE_DIR).join("../bds-core/build.rs")).unwrap();
|
|
assert!(core_build.contains("cargo:rustc-link-lib=framework=CoreML"));
|
|
let server_manifest =
|
|
fs::read_to_string(Path::new(CRATE_DIR).join("../bds-server/Cargo.toml")).unwrap();
|
|
assert!(server_manifest.contains("crate-type = [\"dylib\"]"));
|
|
assert!(!manifest.contains("{ path = \"bds-server\" }"));
|
|
assert!(!manifest.contains("-p bds-server"));
|
|
assert!(
|
|
!Path::new(CRATE_DIR)
|
|
.join("../bds-server/src/main.rs")
|
|
.exists()
|
|
);
|
|
|
|
let packager =
|
|
fs::read_to_string(Path::new(CRATE_DIR).join("../bds-package-runtime/src/main.rs"))
|
|
.unwrap();
|
|
assert!(packager.contains("Command::new(\"codesign\")"));
|
|
assert!(packager.contains("CARGO_PACKAGER_FORMAT"));
|
|
assert!(!packager.contains("--options"));
|
|
}
|
|
|
|
#[test]
|
|
fn tagged_releases_are_built_and_packaged_with_rust_tools() {
|
|
let workspace = Path::new(CRATE_DIR).join("../..");
|
|
let manifest = fs::read_to_string(workspace.join("Cargo.toml")).unwrap();
|
|
assert!(manifest.contains("\"crates/bds-release\""));
|
|
for dependency in [
|
|
"apple-bundles = \"0.21\"",
|
|
"apple-codesign = { version = \"0.29\", default-features = false }",
|
|
"apple-dmg = \"0.5\"",
|
|
] {
|
|
assert!(manifest.contains(dependency), "missing {dependency}");
|
|
}
|
|
|
|
let release_manifest =
|
|
fs::read_to_string(workspace.join("crates/bds-release/Cargo.toml")).unwrap();
|
|
for dependency in [
|
|
"apple-bundles.workspace = true",
|
|
"apple-codesign.workspace = true",
|
|
"apple-dmg.workspace = true",
|
|
"flate2",
|
|
"tar",
|
|
"zip",
|
|
] {
|
|
assert!(
|
|
release_manifest.contains(dependency),
|
|
"release packager is missing {dependency}"
|
|
);
|
|
}
|
|
|
|
let workflow = fs::read_to_string(workspace.join(".gitea/workflows/release.yml")).unwrap();
|
|
serde_yaml::from_str::<serde_yaml::Value>(&workflow).expect("valid release workflow YAML");
|
|
for required in [
|
|
"tags:",
|
|
"runs-on: linux-arm64",
|
|
"cargo-zigbuild",
|
|
"macos-linker-alias",
|
|
"-Lnative=target/macos-linker",
|
|
"aarch64-apple-darwin",
|
|
"x86_64-apple-darwin",
|
|
"aarch64-unknown-linux-gnu",
|
|
"x86_64-unknown-linux-gnu",
|
|
"cargo-xwin",
|
|
"windows-runtime",
|
|
"cargo +${RUST_TOOLCHAIN} xwin cache xwin",
|
|
"/root/.cache/cargo-xwin/xwin/sdk/lib/um/x86_64",
|
|
"-Lnative=target/x86_64-pc-windows-msvc/release",
|
|
"apt-get install --no-install-recommends --yes nasm",
|
|
"x86_64-pc-windows-msvc",
|
|
"bds-release",
|
|
"REBUILD_PUBLISHED_RELEASE: \"true\"",
|
|
"prepare",
|
|
"package",
|
|
"publish",
|
|
"PKG_CONFIG_ALLOW_CROSS",
|
|
"CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER",
|
|
"CFLAGS: -fPIC",
|
|
"CXXFLAGS: -fPIC",
|
|
] {
|
|
assert!(
|
|
workflow.contains(required),
|
|
"release workflow is missing {required}"
|
|
);
|
|
}
|
|
for forbidden in ["python", "curl ", "hdiutil", "makensis", "tar -"] {
|
|
assert!(
|
|
!workflow.contains(forbidden),
|
|
"release workflow must not use host tool {forbidden}"
|
|
);
|
|
}
|
|
assert!(
|
|
!workflow.contains("target-feature=+crt-static"),
|
|
"Windows and downloaded ONNX Runtime must use the same dynamic CRT"
|
|
);
|
|
assert!(
|
|
!workflow.contains("run --release --locked --package bds-release"),
|
|
"the release helper itself must stay unoptimized so cold runner jobs remain practical"
|
|
);
|
|
assert_eq!(
|
|
workflow
|
|
.matches("actions-rust-lang/setup-rust-toolchain@v1")
|
|
.count(),
|
|
4,
|
|
"every release job using the Ubuntu runner image must bootstrap Rust"
|
|
);
|
|
assert_eq!(
|
|
workflow
|
|
.matches("needs: [prepare-release, build-linux-x64]")
|
|
.count(),
|
|
3,
|
|
"the expensive platform builds must wait for the Linux x64 cross-build smoke test"
|
|
);
|
|
|
|
let linux_dependencies =
|
|
fs::read_to_string(workspace.join(".gitea/scripts/install-linux-build-dependencies.sh"))
|
|
.unwrap();
|
|
for required in [
|
|
"libwebkit2gtk-4.1-dev",
|
|
"libgtk-3-dev",
|
|
"libxdo-dev",
|
|
"libwebkit2gtk-4.1-dev:amd64",
|
|
"gcc-x86-64-linux-gnu",
|
|
"Architectures: arm64",
|
|
"--download-only",
|
|
"dpkg-deb --extract",
|
|
"libc.so.6 libm.so.6 libmvec.so.1",
|
|
"cp -a \"$sysroot/usr/lib/x86_64-linux-gnu/$library\"",
|
|
"cp -a \"$sysroot/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2\"",
|
|
"/usr/share/pkgconfig/.",
|
|
"/opt/ruds-x64-sysroot",
|
|
] {
|
|
assert!(
|
|
linux_dependencies.contains(required),
|
|
"Linux dependency setup is missing {required}"
|
|
);
|
|
}
|
|
let multiarch = linux_dependencies
|
|
.find("dpkg --add-architecture amd64")
|
|
.expect("amd64 architecture setup");
|
|
assert!(
|
|
!linux_dependencies.contains("apt-get remove"),
|
|
"cross-build setup must not replace native runner packages"
|
|
);
|
|
let native_source_filter = linux_dependencies
|
|
.find("'/^Architectures:/d; /^Types: deb$/a Architectures: arm64'")
|
|
.expect("native apt architecture filter");
|
|
let native_cross_compiler = linux_dependencies
|
|
.find("install_packages build-essential cmake gcc-x86-64-linux-gnu")
|
|
.expect("native cross compiler setup");
|
|
assert!(
|
|
linux_dependencies[native_source_filter..native_cross_compiler]
|
|
.contains("sudo apt-get update"),
|
|
"native apt indexes must be refreshed after constraining the source architecture"
|
|
);
|
|
assert!(
|
|
native_cross_compiler < multiarch,
|
|
"the native cross compiler must be installed before enabling multiarch"
|
|
);
|
|
assert!(
|
|
linux_dependencies.find("--download-only").unwrap() > multiarch,
|
|
"foreign libraries must only be downloaded after enabling multiarch"
|
|
);
|
|
assert!(workflow.contains("PKG_CONFIG_SYSROOT_DIR: /opt/ruds-x64-sysroot"));
|
|
assert!(
|
|
workflow.contains("link-arg=--sysroot=/opt/ruds-x64-sysroot"),
|
|
"the cross-linker must resolve absolute libc linker-script paths inside the x64 sysroot"
|
|
);
|
|
|
|
let workspace_manifest = fs::read_to_string(workspace.join("Cargo.toml")).unwrap();
|
|
let core_manifest = fs::read_to_string(workspace.join("crates/bds-core/Cargo.toml")).unwrap();
|
|
assert!(
|
|
workspace_manifest.contains("usearch = { version = \"2.26\", default-features = false }"),
|
|
"USearch SIMD backends must be selected explicitly per target"
|
|
);
|
|
assert!(
|
|
core_manifest.contains("[target.'cfg(target_os = \"macos\")'.dependencies]")
|
|
&& core_manifest.contains("[target.'cfg(not(target_os = \"macos\"))'.dependencies]")
|
|
&& core_manifest.contains("usearch = { workspace = true, features = [\"numkong\"] }"),
|
|
"macOS must use portable USearch while native targets keep NumKong SIMD"
|
|
);
|
|
|
|
let release_source =
|
|
fs::read_to_string(workspace.join("crates/bds-release/src/packaging.rs")).unwrap();
|
|
assert!(release_source.contains("LC_ID_DYLIB"));
|
|
assert!(release_source.contains("rewrite_macho_rpaths"));
|
|
assert!(!release_source.contains("Linux releases contain the portable CLI tools"));
|
|
}
|