diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index fda57ecf8..7eae7d31a 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -201,7 +201,7 @@ jobs: # Read the first two lines of the metadata file: version=$(sed -n '1p' metadata.txt) build_time=$(sed -n '2p' metadata.txt) - pdfium_full_version=$(sed -n '11p' metadata.txt) + pdfium_full_version=$(sed -n '10p' metadata.txt) pdfium_chromium_revision=$(echo "$pdfium_full_version" | cut -d'.' -f3) source_commit=$(git rev-parse HEAD) @@ -922,22 +922,15 @@ jobs: # Format the app version: formatted_app_version="v${app_version}" - - # Set the architecture: - if sed --version 2>/dev/null | grep -q GNU; then - sed -i "10s/.*/${{ matrix.dotnet_runtime }}/" metadata.txt - else - sed -i '' "10s/.*/${{ matrix.dotnet_runtime }}/" metadata.txt - fi - + # Next line is the necessary PDFium version. # The format is '137.0.7123.0'. What we need # is the '7123' part: - pdfium_version=$(sed -n '11p' metadata.txt) + pdfium_version=$(sed -n '10p' metadata.txt) pdfium_version=$(echo $pdfium_version | cut -d'.' -f3) # Next line is the vector store version: - vector_store_version="$(sed -n '12p' metadata.txt)" + vector_store_version="$(sed -n '11p' metadata.txt)" # Write the metadata to the environment: echo "APP_VERSION=${app_version}" >> $GITHUB_ENV @@ -996,21 +989,15 @@ jobs: # Format the app version: $formatted_app_version = "v${app_version}" - - # Set the architecture: - $metadata[9] = "${{ matrix.dotnet_runtime }}" - - # Write the changed metadata back to the file: - Set-Content -Path metadata.txt -Value $metadata - + # Next line is the necessary PDFium version. # The format is '137.0.7123.0'. What we need # is the '7123' part: - $pdfium_version = $metadata[10] + $pdfium_version = $metadata[9] $pdfium_version = $pdfium_version.Split('.')[2] # Next line is the vector store version: - $vector_store_version = $metadata[11] + $vector_store_version = $metadata[10] # Write the metadata to the environment: Write-Output "APP_VERSION=${app_version}" >> $env:GITHUB_ENV diff --git a/AGENTS.md b/AGENTS.md index e8b9a8a1a..f42263b08 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -163,10 +163,6 @@ again yourself when `metadata.txt` changes during the session, e.g., after a mer - Commit each finished piece of work as soon as the gate passes, under a short title in US English, and push it right away; in the incremental workflow, do so for each plan item before you stop. A machine idle for long may be reclaimed, and then only the conversation comes back. -- Every Rust build, the gate's included, writes the architecture of the machine into line 10 of - `metadata.txt`, here `linux-x64`. Never commit that line: restore the file with - `git checkout -- metadata.txt` before you commit, or, when your work changed other lines of it, set - line 10 back to its committed value. - Push only to the branch of the session: the one Claude Code designated for it, or the one the developer named. Never push to `main` or any other branch, never force-push, and never rewrite a pushed commit; fix it with a new one instead. diff --git a/app/Build/Commands/UpdateMetadataCommands.cs b/app/Build/Commands/UpdateMetadataCommands.cs index a153e6b7b..2a06ad47c 100644 --- a/app/Build/Commands/UpdateMetadataCommands.cs +++ b/app/Build/Commands/UpdateMetadataCommands.cs @@ -251,7 +251,6 @@ public sealed partial class UpdateMetadataCommands var rid = Environment.GetCurrentRid(); Console.WriteLine("=============================="); - await this.UpdateArchitecture(rid); await this.UpdateTauriVersion(); await this.UpdateVectorStoreVersion(); @@ -845,7 +844,7 @@ public sealed partial class UpdateMetadataCommands private async Task ReadPdfiumVersion() { - const int PDFIUM_VERSION_INDEX = 10; + const int PDFIUM_VERSION_INDEX = 9; var pathMetadata = Environment.GetMetadataPath(); var lines = await File.ReadAllLinesAsync(pathMetadata, Encoding.UTF8); @@ -855,19 +854,6 @@ public sealed partial class UpdateMetadataCommands return shortVersion; } - private async Task UpdateArchitecture(RID rid) - { - const int ARCHITECTURE_INDEX = 9; - - var pathMetadata = Environment.GetMetadataPath(); - var lines = await File.ReadAllLinesAsync(pathMetadata, Encoding.UTF8); - Console.Write($"- Updating architecture to {rid.ToUserFriendlyName()} ..."); - lines[ARCHITECTURE_INDEX] = rid.AsMicrosoftRid(); - - await WriteMetadataLinesAsync(pathMetadata, lines); - Console.WriteLine(" done."); - } - [Command("update-project-hash", Description = "Update the project commit hash")] public async Task UpdateProjectCommitHash() { @@ -1016,7 +1002,7 @@ public sealed partial class UpdateMetadataCommands private async Task UpdateVectorStoreVersion() { - const int VECTOR_STORE_VERSION_INDEX = 11; + const int VECTOR_STORE_VERSION_INDEX = 10; var pathMetadata = Environment.GetMetadataPath(); var lines = await File.ReadAllLinesAsync(pathMetadata, Encoding.UTF8); diff --git a/app/MindWork AI Studio/MindWork AI Studio.csproj b/app/MindWork AI Studio/MindWork AI Studio.csproj index f3993f64d..23c305ead 100644 --- a/app/MindWork AI Studio/MindWork AI Studio.csproj +++ b/app/MindWork AI Studio/MindWork AI Studio.csproj @@ -128,9 +128,15 @@ $([System.String]::Copy( $(Metadata) ).Split( ';' )[ 6 ]) $([System.String]::Copy( $(Metadata) ).Split( ';' )[ 7 ]) $([System.String]::Copy( $(Metadata) ).Split( ';' )[ 8 ]) - $([System.String]::Copy( $(Metadata) ).Split( ';' )[ 9 ]) - $([System.String]::Copy( $(Metadata) ).Split( ';' )[ 10 ]) - $([System.String]::Copy( $(Metadata) ).Split( ';' )[ 11 ]) + + + $(RuntimeIdentifier) + + $([System.String]::Copy( $(Metadata) ).Split( ';' )[ 9 ]) + $([System.String]::Copy( $(Metadata) ).Split( ';' )[ 10 ]) true diff --git a/app/MindWork AI Studio/Tools/Pandoc.cs b/app/MindWork AI Studio/Tools/Pandoc.cs index 709b05d29..366d9a58d 100644 --- a/app/MindWork AI Studio/Tools/Pandoc.cs +++ b/app/MindWork AI Studio/Tools/Pandoc.cs @@ -1,10 +1,8 @@ using System.Diagnostics; using System.Formats.Tar; using System.IO.Compression; -using System.Reflection; using System.Text.RegularExpressions; -using AIStudio.Tools.Metadata; using AIStudio.Tools.Services; using SharedTools; @@ -15,12 +13,8 @@ public static partial class Pandoc { private static string TB(string fallbackEN) => PluginSystem.I18N.I.T(fallbackEN, typeof(Pandoc).Namespace, nameof(Pandoc)); - private static readonly Assembly ASSEMBLY = Assembly.GetExecutingAssembly(); - private static readonly MetaDataArchitectureAttribute META_DATA_ARCH = ASSEMBLY.GetCustomAttribute()!; - - // Use runtime detection instead of metadata to ensure correct RID on dev machines: + // Pandoc is a program of its own, so it has to fit the machine, not the build of AI Studio: private static readonly RID CPU_ARCHITECTURE = RIDExtensions.GetCurrentRID(); - private static readonly RID METADATA_ARCHITECTURE = META_DATA_ARCH.Architecture.ToRID(); private const string DOWNLOAD_URL = "https://github.com/jgm/pandoc/releases/download"; private const string LATEST_URL = "https://github.com/jgm/pandoc/releases/latest"; @@ -66,19 +60,6 @@ public static partial class Pandoc { try { - // - // Log a warning if the runtime-detected RID differs from the metadata RID. - // This can happen on dev machines where the metadata.txt contains stale values. - // We always use the runtime-detected RID for correct behavior. - // - if (!HAS_LOGGED_EXECUTABLE_ONCE && CPU_ARCHITECTURE != METADATA_ARCHITECTURE) - { - LOG.LogWarning( - "Runtime-detected RID '{RuntimeRID}' differs from metadata RID '{MetadataRID}'. Using runtime-detected RID. This is expected on dev machines where metadata.txt may be outdated.", - CPU_ARCHITECTURE.ToUserFriendlyName(), - METADATA_ARCHITECTURE.ToUserFriendlyName()); - } - var preparedProcess = await PreparePandocProcess().AddArgument("--version").BuildAsync(rustService); if (!HAS_LOGGED_EXECUTABLE_ONCE) { diff --git a/app/MindWork AI Studio/Tools/PandocProcessBuilder.cs b/app/MindWork AI Studio/Tools/PandocProcessBuilder.cs index e7711a51a..87d1b27f4 100644 --- a/app/MindWork AI Studio/Tools/PandocProcessBuilder.cs +++ b/app/MindWork AI Studio/Tools/PandocProcessBuilder.cs @@ -1,7 +1,5 @@ using System.Diagnostics; -using System.Reflection; -using AIStudio.Tools.Metadata; using AIStudio.Tools.Rust; using AIStudio.Tools.Services; @@ -11,12 +9,8 @@ namespace AIStudio.Tools; public sealed class PandocProcessBuilder { - private static readonly Assembly ASSEMBLY = Assembly.GetExecutingAssembly(); - private static readonly MetaDataArchitectureAttribute META_DATA_ARCH = ASSEMBLY.GetCustomAttribute()!; - - // Use runtime detection instead of metadata to ensure correct RID on dev machines: + // Pandoc is a program of its own, so it has to fit the machine, not the build of AI Studio: private static readonly RID CPU_ARCHITECTURE = RIDExtensions.GetCurrentRID(); - private static readonly RID METADATA_ARCHITECTURE = META_DATA_ARCH.Architecture.ToRID(); private static readonly ILogger LOGGER = Program.LOGGER_FACTORY.CreateLogger(nameof(PandocProcessBuilder)); private const string FLATPAK_PANDOC_PLUGIN_BIN_DIRECTORY = "/app/plugins/pandoc/bin"; @@ -139,19 +133,6 @@ public sealed class PandocProcessBuilder try { - // - // Log a warning if the runtime-detected RID differs from the metadata RID. - // This can happen on dev machines where the metadata.txt contains stale values. - // We always use the runtime-detected RID for correct behavior. - // - if (shouldLog && CPU_ARCHITECTURE != METADATA_ARCHITECTURE) - { - LOGGER.LogWarning( - "Runtime-detected RID '{RuntimeRID}' differs from metadata RID '{MetadataRID}'. Using runtime-detected RID. This is expected on dev machines where metadata.txt may be outdated.", - CPU_ARCHITECTURE.ToUserFriendlyName(), - METADATA_ARCHITECTURE.ToUserFriendlyName()); - } - // // First, we try to find the pandoc executable in the data directory. // Any local installation should be preferred over the system-wide installation. diff --git a/app/SharedTools/RIDExtensions.cs b/app/SharedTools/RIDExtensions.cs index d340e9a2f..e8552c3da 100644 --- a/app/SharedTools/RIDExtensions.cs +++ b/app/SharedTools/RIDExtensions.cs @@ -8,8 +8,8 @@ public static class RIDExtensions /// Detects the current Runtime Identifier (RID) at runtime based on OS and architecture. /// /// - /// This method should be preferred over reading the RID from metadata, - /// as the metadata may contain stale values in development environments. + /// This is the machine which runs the code. The architecture in the metadata of AI Studio + /// is the platform AI Studio was built for instead; both can differ under emulation. /// /// The detected RID for the current platform. public static RID GetCurrentRID() diff --git a/metadata.txt b/metadata.txt index 4afa201ab..be824b51d 100644 --- a/metadata.txt +++ b/metadata.txt @@ -7,6 +7,5 @@ 8.15.0 2.11.5 9f102728b59, release -osx-arm64 148.0.7763.0 0.8.0 diff --git a/runtime/build.rs b/runtime/build.rs index af6716f8d..2fecf9eb8 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -7,20 +7,19 @@ fn main() { println!("cargo:rustc-env=OUT_DIR={}", out_dir.to_str().unwrap()); // - // When we are in debug mode, we want to set the current RID - // to the current architecture. This is necessary, so that - // the developers get the right behavior. - // - // We read the current OS and architecture and overwrite the - // current RID in the metadata file (line #10). + // The runtime reports the platform it is built for. Cargo runs this + // build script on the machine which builds, so std::env::consts would + // name that machine. Both differ when we cross-compile, e.g., for + // Intel-based Macs on an ARM-based one. Hence, we read the target + // from Cargo and pass its RID on to the compiler. // // We have to take care of different naming conventions. The // following RIDs are supported: win-x64, win-arm64, linux-x64, // linux-arm64, osx-x64, osx-arm64. // - let current_os = std::env::consts::OS; - let current_arch = std::env::consts::ARCH; - let rid = match (current_os, current_arch) { + let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); + let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + let rid = match (target_os.as_str(), target_arch.as_str()) { ("windows", "x86_64") => "win-x64", ("windows", "aarch64") => "win-arm64", @@ -30,28 +29,17 @@ fn main() { ("macos", "x86_64") => "osx-x64", ("macos", "aarch64") => "osx-arm64", - _ => panic!("Unsupported OS or architecture: {current_os} {current_arch}"), + _ => panic!("Unsupported OS or architecture: {target_os} {target_arch}"), }; - let metadata = include_str!("../metadata.txt"); - let mut metadata_lines = metadata.lines().collect::>(); - metadata_lines[9] = rid; - - // Every line ends with a line break, the last one included. The build - // script of the .NET side writes the file the same way: - let mut new_metadata = metadata_lines.join("\n"); - new_metadata.push('\n'); - - // Write only on a change to avoid unnecessary rewrites: - if new_metadata != metadata { - std::fs::write("../metadata.txt", new_metadata).unwrap(); - } + println!("cargo:rustc-env=AI_STUDIO_ARCHITECTURE={rid}"); // // Read the current version and update the // Rust and Tauri configuration files: // - let version = metadata_lines[0]; + let metadata = include_str!("../metadata.txt"); + let version = metadata.lines().next().unwrap(); update_cargo_toml("Cargo.toml", version); update_tauri_conf("tauri.conf.json", version); } diff --git a/runtime/src/metadata.rs b/runtime/src/metadata.rs index df72640b2..b5dc70aa8 100644 --- a/runtime/src/metadata.rs +++ b/runtime/src/metadata.rs @@ -38,12 +38,12 @@ impl MetaData { let mud_blazor_version = metadata_lines.next().unwrap(); let tauri_version = metadata_lines.next().unwrap(); let app_commit_hash = metadata_lines.next().unwrap(); - let architecture = metadata_lines.next().unwrap(); let pdfium_version = metadata_lines.next().unwrap(); let vector_store_version = metadata_lines.next().unwrap(); let metadata = MetaData { - architecture: architecture.to_string(), + // The build script names the platform the runtime is built for: + architecture: env!("AI_STUDIO_ARCHITECTURE").to_string(), app_commit_hash: app_commit_hash.to_string(), app_version: app_version.to_string(), build_number: build_number.to_string(), diff --git a/runtime/src/pandoc.rs b/runtime/src/pandoc.rs index b5fffc3d5..c36a8a443 100644 --- a/runtime/src/pandoc.rs +++ b/runtime/src/pandoc.rs @@ -6,10 +6,7 @@ use std::sync::OnceLock; use log::{info, warn}; use tokio::process::Command; use crate::environment::{DATA_DIRECTORY, is_flatpak}; -use crate::metadata::META_DATA; -/// Tracks whether the RID mismatch warning has been logged. -static HAS_LOGGED_RID_MISMATCH: OnceLock<()> = OnceLock::new(); static HAS_LOGGED_PANDOC_PATH: OnceLock<()> = OnceLock::new(); const FLATPAK_PANDOC_PLUGIN_BIN_DIRECTORY: &str = "/app/plugins/pandoc/bin"; @@ -243,47 +240,8 @@ impl PandocProcessBuilder { } } - /// Determines the executable name based on the current OS at runtime. - /// - /// This uses runtime detection instead of metadata to ensure correct behavior - /// on dev machines where the metadata may contain stale values. + /// Determines the executable name based on the OS the runtime is built for. fn pandoc_executable_name() -> String { - // Log a warning (once) if the runtime OS differs from the metadata architecture. - // This can happen on dev machines where the metadata.txt contains stale values. - HAS_LOGGED_RID_MISMATCH.get_or_init(|| { - let runtime_os = std::env::consts::OS; - let runtime_arch = std::env::consts::ARCH; - - if let Ok(metadata) = META_DATA.lock() && let Some(metadata) = metadata.as_ref() { - let metadata_arch = &metadata.architecture; - - // Determine expected OS from metadata: - let metadata_is_windows = metadata_arch.starts_with("win-"); - let metadata_is_macos = metadata_arch.starts_with("osx-"); - let metadata_is_linux = metadata_arch.starts_with("linux-"); - - // Compare with runtime OS: - let runtime_is_windows = runtime_os == "windows"; - let runtime_is_macos = runtime_os == "macos"; - let runtime_is_linux = runtime_os == "linux"; - - let os_mismatch = (metadata_is_windows != runtime_is_windows) - || (metadata_is_macos != runtime_is_macos) - || (metadata_is_linux != runtime_is_linux); - - if os_mismatch { - warn!( - Source = "Pandoc"; - "Runtime-detected OS '{}-{}' differs from metadata architecture '{}'. Using runtime-detected OS. This is expected on dev machines where metadata.txt may be outdated.", - runtime_os, - runtime_arch, - metadata_arch - ); - } - } - }); - - // Use std::env::consts::OS for runtime detection instead of metadata match std::env::consts::OS { "windows" => "pandoc.exe".to_string(), _ => "pandoc".to_string(),