mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 04:55:42 +09:00
fix(desktop): restore Windows canary builds (#2017)
This commit is contained in:
1 parent
28184f8d4d
commit
da3922586a
1 file changed
+97
-30
+97
-30
@@ -897,10 +897,32 @@ fn apt_get(args: &[&str]) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn install_msvc_arm64_tools_step() -> Result<()> {
|
fn install_msvc_arm64_tools_step() -> Result<()> {
|
||||||
let installer =
|
let program_files_x86 = env::var_os("ProgramFiles(x86)")
|
||||||
Path::new(r"C:\Program Files (x86)\Microsoft Visual Studio\Installer\setup.exe");
|
.map(PathBuf::from)
|
||||||
let install_path = Path::new(r"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools");
|
.ok_or_else(|| anyhow!("ProgramFiles(x86) is not set on the Windows runner"))?;
|
||||||
run_command(CommandSpec::new(installer).args([
|
let installer_dir = program_files_x86
|
||||||
|
.join("Microsoft Visual Studio")
|
||||||
|
.join("Installer");
|
||||||
|
let installer = installer_dir.join("setup.exe");
|
||||||
|
let vswhere = installer_dir.join("vswhere.exe");
|
||||||
|
ensure!(
|
||||||
|
vswhere.is_file(),
|
||||||
|
"Visual Studio locator not found: {}",
|
||||||
|
vswhere.display()
|
||||||
|
);
|
||||||
|
|
||||||
|
let install_path = resolve_visual_studio_install_path(&vswhere)?;
|
||||||
|
if let Some(linker) = find_msvc_arm64_linker(&install_path)? {
|
||||||
|
println!("ARM64 cross link.exe: {}", linker.display());
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
ensure!(
|
||||||
|
installer.is_file(),
|
||||||
|
"Visual Studio installer not found: {}",
|
||||||
|
installer.display()
|
||||||
|
);
|
||||||
|
|
||||||
|
run_command(CommandSpec::new(&installer).args([
|
||||||
"modify",
|
"modify",
|
||||||
"--installPath",
|
"--installPath",
|
||||||
install_path.to_string_lossy().as_ref(),
|
install_path.to_string_lossy().as_ref(),
|
||||||
@@ -924,9 +946,51 @@ fn install_msvc_arm64_tools_step() -> Result<()> {
|
|||||||
"VS installer did not finish within the timeout."
|
"VS installer did not finish within the timeout."
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut found = false;
|
let linker = find_msvc_arm64_linker(&install_path)?.ok_or_else(|| {
|
||||||
|
anyhow!(
|
||||||
|
"ARM64 cross-build tools were not installed under {}\\VC\\Tools\\MSVC\\*\\bin\\HostX64\\arm64",
|
||||||
|
install_path.display()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
println!("ARM64 cross link.exe: {}", linker.display());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve_visual_studio_install_path(vswhere: &Path) -> Result<PathBuf> {
|
||||||
|
let output = output_text(CommandSpec::new(vswhere).args([
|
||||||
|
"-products",
|
||||||
|
"*",
|
||||||
|
"-latest",
|
||||||
|
"-prerelease",
|
||||||
|
"-property",
|
||||||
|
"installationPath",
|
||||||
|
]))?;
|
||||||
|
let paths = output
|
||||||
|
.lines()
|
||||||
|
.map(str::trim)
|
||||||
|
.filter(|line| !line.is_empty())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
ensure!(
|
||||||
|
paths.len() == 1,
|
||||||
|
"vswhere returned {} Visual Studio installation paths; expected exactly one",
|
||||||
|
paths.len()
|
||||||
|
);
|
||||||
|
let install_path = PathBuf::from(paths[0]);
|
||||||
|
ensure!(
|
||||||
|
install_path.is_dir(),
|
||||||
|
"vswhere returned a missing Visual Studio installation: {}",
|
||||||
|
install_path.display()
|
||||||
|
);
|
||||||
|
println!("Visual Studio installation: {}", install_path.display());
|
||||||
|
Ok(install_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_msvc_arm64_linker(install_path: &Path) -> Result<Option<PathBuf>> {
|
||||||
let msvc_root = install_path.join("VC").join("Tools").join("MSVC");
|
let msvc_root = install_path.join("VC").join("Tools").join("MSVC");
|
||||||
if msvc_root.exists() {
|
if !msvc_root.is_dir() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
let mut linkers = Vec::new();
|
||||||
for entry in fs::read_dir(&msvc_root)
|
for entry in fs::read_dir(&msvc_root)
|
||||||
.with_context(|| format!("Failed to read {}", msvc_root.display()))?
|
.with_context(|| format!("Failed to read {}", msvc_root.display()))?
|
||||||
{
|
{
|
||||||
@@ -936,18 +1000,12 @@ fn install_msvc_arm64_tools_step() -> Result<()> {
|
|||||||
.join("HostX64")
|
.join("HostX64")
|
||||||
.join("arm64")
|
.join("arm64")
|
||||||
.join("link.exe");
|
.join("link.exe");
|
||||||
if candidate.exists() {
|
if candidate.is_file() {
|
||||||
println!("ARM64 cross link.exe: {}", candidate.display());
|
linkers.push(candidate);
|
||||||
found = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
linkers.sort();
|
||||||
ensure!(
|
Ok(linkers.pop())
|
||||||
found,
|
|
||||||
"ARM64 cross-build tools were not installed under {}\\*\\bin\\HostX64\\arm64.",
|
|
||||||
msvc_root.display()
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn windows_installer_process_running() -> Result<bool> {
|
fn windows_installer_process_running() -> Result<bool> {
|
||||||
@@ -1823,7 +1881,16 @@ fn create_portable_zip_windows_step() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FLUXER_WINDOWS_SIGNER_COMMON_NAME: &str = "Fluxer Platform AB";
|
const FLUXER_WINDOWS_SIGNER_COMMON_NAME: &str = "Fluxer Platform AB";
|
||||||
const THIRD_PARTY_PUBLISHER_ALLOWLIST: &[&str] = &[];
|
const THIRD_PARTY_WINDOWS_SIGNATURE_ALLOWLIST: &[(&str, &str)] = &[
|
||||||
|
(
|
||||||
|
"d3dcompiler_47.dll",
|
||||||
|
"CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"dxil.dll",
|
||||||
|
"CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||||
|
),
|
||||||
|
];
|
||||||
const KNOWN_OPTIONAL_WINDOWS_PE_INVENTORY: &[&str] = &["fluxer-vulkan-layer.win32-ia32-msvc.dll"];
|
const KNOWN_OPTIONAL_WINDOWS_PE_INVENTORY: &[&str] = &["fluxer-vulkan-layer.win32-ia32-msvc.dll"];
|
||||||
const WINDOWS_NATIVE_ADDON_STEMS: &[&str] = &[
|
const WINDOWS_NATIVE_ADDON_STEMS: &[&str] = &[
|
||||||
"hardware-encoder",
|
"hardware-encoder",
|
||||||
@@ -2144,7 +2211,7 @@ fn assert_fluxer_signed(row: &SignatureRow) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_third_party_signed(row: &SignatureRow) -> Result<()> {
|
fn assert_third_party_signed(row: &SignatureRow, relative: &str) -> Result<()> {
|
||||||
ensure!(
|
ensure!(
|
||||||
row.status == "Valid",
|
row.status == "Valid",
|
||||||
"Authenticode status is {} (expected Valid)",
|
"Authenticode status is {} (expected Valid)",
|
||||||
@@ -2154,11 +2221,13 @@ fn assert_third_party_signed(row: &SignatureRow) -> Result<()> {
|
|||||||
.subject
|
.subject
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.ok_or_else(|| anyhow!("Authenticode signature has no signer certificate subject"))?;
|
.ok_or_else(|| anyhow!("Authenticode signature has no signer certificate subject"))?;
|
||||||
let common_name = certificate_common_name(subject)
|
|
||||||
.ok_or_else(|| anyhow!("Signer subject has no CN= component: {subject}"))?;
|
|
||||||
ensure!(
|
ensure!(
|
||||||
THIRD_PARTY_PUBLISHER_ALLOWLIST.contains(&common_name),
|
THIRD_PARTY_WINDOWS_SIGNATURE_ALLOWLIST
|
||||||
"Signer CN '{common_name}' is not an allowlisted third-party publisher"
|
.iter()
|
||||||
|
.any(|(allowed_path, allowed_subject)| {
|
||||||
|
relative.eq_ignore_ascii_case(allowed_path) && subject == *allowed_subject
|
||||||
|
}),
|
||||||
|
"Signer subject '{subject}' is not allowlisted for {relative}"
|
||||||
);
|
);
|
||||||
ensure!(
|
ensure!(
|
||||||
row.ts_subject.is_some(),
|
row.ts_subject.is_some(),
|
||||||
@@ -2167,10 +2236,10 @@ fn assert_third_party_signed(row: &SignatureRow) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_signed_by_known_publisher(row: &SignatureRow) -> Result<()> {
|
fn assert_signed_by_known_publisher(row: &SignatureRow, relative: &str) -> Result<()> {
|
||||||
match assert_fluxer_signed(row) {
|
match assert_fluxer_signed(row) {
|
||||||
Ok(()) => Ok(()),
|
Ok(()) => Ok(()),
|
||||||
Err(fluxer_error) => assert_third_party_signed(row)
|
Err(fluxer_error) => assert_third_party_signed(row, relative)
|
||||||
.map_err(|third_party_error| anyhow!("{fluxer_error}; {third_party_error}")),
|
.map_err(|third_party_error| anyhow!("{fluxer_error}; {third_party_error}")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2333,22 +2402,20 @@ fn verify_windows_pe_signatures(
|
|||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if let Err(error) = assert_signed_by_known_publisher(row) {
|
if let Err(error) = assert_signed_by_known_publisher(row, &relative) {
|
||||||
failures.push(format!("{relative}: {error}"));
|
failures.push(format!("{relative}: {error}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ensure!(
|
ensure!(
|
||||||
failures.is_empty(),
|
failures.is_empty(),
|
||||||
"{label}: {} of {} Windows binaries are not signed by '{}':\n{}",
|
"{label}: {} of {} Windows binaries do not have an approved signature:\n{}",
|
||||||
failures.len(),
|
failures.len(),
|
||||||
files.len(),
|
files.len(),
|
||||||
FLUXER_WINDOWS_SIGNER_COMMON_NAME,
|
|
||||||
failures.join("\n")
|
failures.join("\n")
|
||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
"{label}: verified {} Windows binaries signed by '{}'.",
|
"{label}: verified {} Windows binary signatures.",
|
||||||
files.len(),
|
files.len()
|
||||||
FLUXER_WINDOWS_SIGNER_COMMON_NAME
|
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user