diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 544b6a95..0f9ac560 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -784,17 +784,26 @@ jobs: sudo apt-get update sudo apt-get install -y libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchelf libfuse2 xdg-utils gstreamer1.0-plugins-base gstreamer1.0-plugins-good - - name: Place a stand-in for the .NET sidecar + - name: Place stand-ins for what Tauri's build script expects run: | - # Tauri's build script copies the .NET app in as a sidecar and refuses to run while that - # file is missing, so nothing Rust compiles without it. This job never bundles anything - # and never starts the app; it compiles, tests and lints the Rust code. An empty file is - # therefore enough, and publishing the real one would cost minutes for a binary nobody - # here runs. + # Tauri's build script insists that everything the configuration lists is already there, + # and refuses to run otherwise -- so nothing Rust compiles without it. Two of those + # things are products of a build which has not run here: the .NET app as a sidecar, and + # the PDF library which the build downloads into the resources. The other two resource + # directories, notices and tokenizers, are in the repository and need nothing. + # + # This job never bundles anything and never starts the app; it compiles, tests and lints + # the Rust code, and no test opens either file. Empty stand-ins are therefore enough, + # while publishing the sidecar and downloading the library would cost minutes for files + # nobody here reads. Should a Rust test ever need the real library, this job has to + # deploy it the way build_main does instead of placing a stand-in. mkdir -p "app/MindWork AI Studio/bin/dist" touch "app/MindWork AI Studio/bin/dist/mindworkAIStudioServer-x86_64-unknown-linux-gnu" chmod +x "app/MindWork AI Studio/bin/dist/mindworkAIStudioServer-x86_64-unknown-linux-gnu" + mkdir -p runtime/resources/libraries + touch runtime/resources/libraries/stand-in-for-verify.txt + - name: Run the quality gate run: | cd "app/Build" diff --git a/app/Build/Commands/VerifyCommand.cs b/app/Build/Commands/VerifyCommand.cs index 2e65ba72..2f9b4e71 100644 --- a/app/Build/Commands/VerifyCommand.cs +++ b/app/Build/Commands/VerifyCommand.cs @@ -35,7 +35,7 @@ public sealed class VerifyCommand }; var runtimeDirectory = Environment.GetRustRuntimeDirectory(); - if (HasSidecar()) + if (WhatTauriExpectsIsThere()) { results.Add(("Rust tests", await CommandRunner.RunAsync(runtimeDirectory, "cargo", "test"))); results.Add(("Clippy", await CommandRunner.RunAsync(runtimeDirectory, "cargo", "clippy --all-targets -- -D warnings"))); @@ -43,12 +43,13 @@ public sealed class VerifyCommand else { // - // Tauri's build script copies the .NET app in as a sidecar and refuses to run at all - // while that file is missing, so nothing Rust compiles without it. Failing here would - // be a trap rather than a gate: the way to produce the sidecar is `dotnet run build`, - // and that command runs this gate first -- a fresh clone would never get past it. + // Tauri's build script insists that everything the configuration lists is already + // there and refuses to run otherwise, so nothing Rust compiles until a build has + // produced those files once. Failing here would be a trap rather than a gate: the way + // to produce them is `dotnet run build`, and that command runs this gate first -- a + // fresh clone would never get past it. // - Console.WriteLine("- Skipping the Rust tests and Clippy: the .NET sidecar is missing, and Tauri's build script needs it before anything Rust compiles."); + Console.WriteLine("- Skipping the Rust tests and Clippy: the .NET sidecar or the downloaded libraries are missing, and Tauri's build script needs both before anything Rust compiles."); Console.WriteLine(" Run 'dotnet run build --skip-verify' once. From then on, this part of the gate runs with the rest."); } @@ -70,9 +71,22 @@ public sealed class VerifyCommand return 1; } - private static bool HasSidecar() + /// + /// Whether a build has already produced the files Tauri's build script reads. + /// + /// + /// Both are products of a build rather than of the repository: the .NET app arrives as a + /// sidecar, and the PDF library is downloaded into the resources. The other resource + /// directories the configuration names are in the repository and are always there. + /// + /// True, when cargo can get past the build script. + private static bool WhatTauriExpectsIsThere() { var distributionDirectory = Path.Combine(Environment.GetAIStudioDirectory(), "bin", "dist"); - return Directory.Exists(distributionDirectory) && Directory.EnumerateFiles(distributionDirectory, $"{SIDECAR_PREFIX}*").Any(); + if (!Directory.Exists(distributionDirectory) || !Directory.EnumerateFiles(distributionDirectory, $"{SIDECAR_PREFIX}*").Any()) + return false; + + var librariesDirectory = Path.Combine(Environment.GetRustRuntimeDirectory(), "resources", "libraries"); + return Directory.Exists(librariesDirectory) && Directory.EnumerateFiles(librariesDirectory).Any(); } } \ No newline at end of file