Took the architecture from the build target instead of metadata.txt (#1070)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-10-16 08:13:18 +02:00
1 parent db2cbaa71e
commit 940d214429
11 files changed
+37 -155

No files matched your search

+7 -20
View File
@@ -201,7 +201,7 @@ jobs:
# Read the first two lines of the metadata file: # Read the first two lines of the metadata file:
version=$(sed -n '1p' metadata.txt) version=$(sed -n '1p' metadata.txt)
build_time=$(sed -n '2p' 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) pdfium_chromium_revision=$(echo "$pdfium_full_version" | cut -d'.' -f3)
source_commit=$(git rev-parse HEAD) source_commit=$(git rev-parse HEAD)
@@ -922,22 +922,15 @@ jobs:
# Format the app version: # Format the app version:
formatted_app_version="v${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. # Next line is the necessary PDFium version.
# The format is '137.0.7123.0'. What we need # The format is '137.0.7123.0'. What we need
# is the '7123' part: # 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) pdfium_version=$(echo $pdfium_version | cut -d'.' -f3)
# Next line is the vector store version: # 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: # Write the metadata to the environment:
echo "APP_VERSION=${app_version}" >> $GITHUB_ENV echo "APP_VERSION=${app_version}" >> $GITHUB_ENV
@@ -996,21 +989,15 @@ jobs:
# Format the app version: # Format the app version:
$formatted_app_version = "v${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. # Next line is the necessary PDFium version.
# The format is '137.0.7123.0'. What we need # The format is '137.0.7123.0'. What we need
# is the '7123' part: # is the '7123' part:
$pdfium_version = $metadata[10] $pdfium_version = $metadata[9]
$pdfium_version = $pdfium_version.Split('.')[2] $pdfium_version = $pdfium_version.Split('.')[2]
# Next line is the vector store version: # Next line is the vector store version:
$vector_store_version = $metadata[11] $vector_store_version = $metadata[10]
# Write the metadata to the environment: # Write the metadata to the environment:
Write-Output "APP_VERSION=${app_version}" >> $env:GITHUB_ENV Write-Output "APP_VERSION=${app_version}" >> $env:GITHUB_ENV
-4
View File
@@ -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 - 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 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. 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 - 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; 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. fix it with a new one instead.
+2 -16
View File
@@ -251,7 +251,6 @@ public sealed partial class UpdateMetadataCommands
var rid = Environment.GetCurrentRid(); var rid = Environment.GetCurrentRid();
Console.WriteLine("=============================="); Console.WriteLine("==============================");
await this.UpdateArchitecture(rid);
await this.UpdateTauriVersion(); await this.UpdateTauriVersion();
await this.UpdateVectorStoreVersion(); await this.UpdateVectorStoreVersion();
@@ -845,7 +844,7 @@ public sealed partial class UpdateMetadataCommands
private async Task<string> ReadPdfiumVersion() private async Task<string> ReadPdfiumVersion()
{ {
const int PDFIUM_VERSION_INDEX = 10; const int PDFIUM_VERSION_INDEX = 9;
var pathMetadata = Environment.GetMetadataPath(); var pathMetadata = Environment.GetMetadataPath();
var lines = await File.ReadAllLinesAsync(pathMetadata, Encoding.UTF8); var lines = await File.ReadAllLinesAsync(pathMetadata, Encoding.UTF8);
@@ -855,19 +854,6 @@ public sealed partial class UpdateMetadataCommands
return shortVersion; 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")] [Command("update-project-hash", Description = "Update the project commit hash")]
public async Task UpdateProjectCommitHash() public async Task UpdateProjectCommitHash()
{ {
@@ -1016,7 +1002,7 @@ public sealed partial class UpdateMetadataCommands
private async Task UpdateVectorStoreVersion() private async Task UpdateVectorStoreVersion()
{ {
const int VECTOR_STORE_VERSION_INDEX = 11; const int VECTOR_STORE_VERSION_INDEX = 10;
var pathMetadata = Environment.GetMetadataPath(); var pathMetadata = Environment.GetMetadataPath();
var lines = await File.ReadAllLinesAsync(pathMetadata, Encoding.UTF8); var lines = await File.ReadAllLinesAsync(pathMetadata, Encoding.UTF8);
@@ -128,9 +128,15 @@
<MetaMudBlazorVersion>$([System.String]::Copy( $(Metadata) ).Split( ';' )[ 6 ])</MetaMudBlazorVersion> <MetaMudBlazorVersion>$([System.String]::Copy( $(Metadata) ).Split( ';' )[ 6 ])</MetaMudBlazorVersion>
<MetaTauriVersion>$([System.String]::Copy( $(Metadata) ).Split( ';' )[ 7 ])</MetaTauriVersion> <MetaTauriVersion>$([System.String]::Copy( $(Metadata) ).Split( ';' )[ 7 ])</MetaTauriVersion>
<MetaAppCommitHash>$([System.String]::Copy( $(Metadata) ).Split( ';' )[ 8 ])</MetaAppCommitHash> <MetaAppCommitHash>$([System.String]::Copy( $(Metadata) ).Split( ';' )[ 8 ])</MetaAppCommitHash>
<MetaArchitecture>$([System.String]::Copy( $(Metadata) ).Split( ';' )[ 9 ])</MetaArchitecture>
<MetaPdfiumVersion>$([System.String]::Copy( $(Metadata) ).Split( ';' )[ 10 ])</MetaPdfiumVersion> <!--
<MetaVectorStoreVersion>$([System.String]::Copy( $(Metadata) ).Split( ';' )[ 11 ])</MetaVectorStoreVersion> The architecture is the one the app is built for. The build script and the pipeline pass it to
dotnet publish; in any other build, SelfContained makes the SDK pick the RID of this machine.
-->
<MetaArchitecture>$(RuntimeIdentifier)</MetaArchitecture>
<MetaPdfiumVersion>$([System.String]::Copy( $(Metadata) ).Split( ';' )[ 9 ])</MetaPdfiumVersion>
<MetaVectorStoreVersion>$([System.String]::Copy( $(Metadata) ).Split( ';' )[ 10 ])</MetaVectorStoreVersion>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo> <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
+1 -20
View File
@@ -1,10 +1,8 @@
using System.Diagnostics; using System.Diagnostics;
using System.Formats.Tar; using System.Formats.Tar;
using System.IO.Compression; using System.IO.Compression;
using System.Reflection;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using AIStudio.Tools.Metadata;
using AIStudio.Tools.Services; using AIStudio.Tools.Services;
using SharedTools; 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 string TB(string fallbackEN) => PluginSystem.I18N.I.T(fallbackEN, typeof(Pandoc).Namespace, nameof(Pandoc));
private static readonly Assembly ASSEMBLY = Assembly.GetExecutingAssembly(); // Pandoc is a program of its own, so it has to fit the machine, not the build of AI Studio:
private static readonly MetaDataArchitectureAttribute META_DATA_ARCH = ASSEMBLY.GetCustomAttribute<MetaDataArchitectureAttribute>()!;
// Use runtime detection instead of metadata to ensure correct RID on dev machines:
private static readonly RID CPU_ARCHITECTURE = RIDExtensions.GetCurrentRID(); 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 DOWNLOAD_URL = "https://github.com/jgm/pandoc/releases/download";
private const string LATEST_URL = "https://github.com/jgm/pandoc/releases/latest"; private const string LATEST_URL = "https://github.com/jgm/pandoc/releases/latest";
@@ -66,19 +60,6 @@ public static partial class Pandoc
{ {
try 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); var preparedProcess = await PreparePandocProcess().AddArgument("--version").BuildAsync(rustService);
if (!HAS_LOGGED_EXECUTABLE_ONCE) if (!HAS_LOGGED_EXECUTABLE_ONCE)
{ {
@@ -1,7 +1,5 @@
using System.Diagnostics; using System.Diagnostics;
using System.Reflection;
using AIStudio.Tools.Metadata;
using AIStudio.Tools.Rust; using AIStudio.Tools.Rust;
using AIStudio.Tools.Services; using AIStudio.Tools.Services;
@@ -11,12 +9,8 @@ namespace AIStudio.Tools;
public sealed class PandocProcessBuilder public sealed class PandocProcessBuilder
{ {
private static readonly Assembly ASSEMBLY = Assembly.GetExecutingAssembly(); // Pandoc is a program of its own, so it has to fit the machine, not the build of AI Studio:
private static readonly MetaDataArchitectureAttribute META_DATA_ARCH = ASSEMBLY.GetCustomAttribute<MetaDataArchitectureAttribute>()!;
// Use runtime detection instead of metadata to ensure correct RID on dev machines:
private static readonly RID CPU_ARCHITECTURE = RIDExtensions.GetCurrentRID(); 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 static readonly ILogger LOGGER = Program.LOGGER_FACTORY.CreateLogger(nameof(PandocProcessBuilder));
private const string FLATPAK_PANDOC_PLUGIN_BIN_DIRECTORY = "/app/plugins/pandoc/bin"; private const string FLATPAK_PANDOC_PLUGIN_BIN_DIRECTORY = "/app/plugins/pandoc/bin";
@@ -139,19 +133,6 @@ public sealed class PandocProcessBuilder
try 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. // First, we try to find the pandoc executable in the data directory.
// Any local installation should be preferred over the system-wide installation. // Any local installation should be preferred over the system-wide installation.
+2 -2
View File
@@ -8,8 +8,8 @@ public static class RIDExtensions
/// Detects the current Runtime Identifier (RID) at runtime based on OS and architecture. /// Detects the current Runtime Identifier (RID) at runtime based on OS and architecture.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This method should be preferred over reading the RID from metadata, /// This is the machine which runs the code. The architecture in the metadata of AI Studio
/// as the metadata may contain stale values in development environments. /// is the platform AI Studio was built for instead; both can differ under emulation.
/// </remarks> /// </remarks>
/// <returns>The detected RID for the current platform.</returns> /// <returns>The detected RID for the current platform.</returns>
public static RID GetCurrentRID() public static RID GetCurrentRID()
-1
View File
@@ -7,6 +7,5 @@
8.15.0 8.15.0
2.11.5 2.11.5
9f102728b59, release 9f102728b59, release
osx-arm64
148.0.7763.0 148.0.7763.0
0.8.0 0.8.0
+12 -24
View File
@@ -7,20 +7,19 @@ fn main() {
println!("cargo:rustc-env=OUT_DIR={}", out_dir.to_str().unwrap()); println!("cargo:rustc-env=OUT_DIR={}", out_dir.to_str().unwrap());
// //
// When we are in debug mode, we want to set the current RID // The runtime reports the platform it is built for. Cargo runs this
// to the current architecture. This is necessary, so that // build script on the machine which builds, so std::env::consts would
// the developers get the right behavior. // 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
// We read the current OS and architecture and overwrite the // from Cargo and pass its RID on to the compiler.
// current RID in the metadata file (line #10).
// //
// We have to take care of different naming conventions. The // We have to take care of different naming conventions. The
// following RIDs are supported: win-x64, win-arm64, linux-x64, // following RIDs are supported: win-x64, win-arm64, linux-x64,
// linux-arm64, osx-x64, osx-arm64. // linux-arm64, osx-x64, osx-arm64.
// //
let current_os = std::env::consts::OS; let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
let current_arch = std::env::consts::ARCH; let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
let rid = match (current_os, current_arch) { let rid = match (target_os.as_str(), target_arch.as_str()) {
("windows", "x86_64") => "win-x64", ("windows", "x86_64") => "win-x64",
("windows", "aarch64") => "win-arm64", ("windows", "aarch64") => "win-arm64",
@@ -30,28 +29,17 @@ fn main() {
("macos", "x86_64") => "osx-x64", ("macos", "x86_64") => "osx-x64",
("macos", "aarch64") => "osx-arm64", ("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"); println!("cargo:rustc-env=AI_STUDIO_ARCHITECTURE={rid}");
let mut metadata_lines = metadata.lines().collect::<Vec<_>>();
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();
}
// //
// Read the current version and update the // Read the current version and update the
// Rust and Tauri configuration files: // 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_cargo_toml("Cargo.toml", version);
update_tauri_conf("tauri.conf.json", version); update_tauri_conf("tauri.conf.json", version);
} }
+2 -2
View File
@@ -38,12 +38,12 @@ impl MetaData {
let mud_blazor_version = metadata_lines.next().unwrap(); let mud_blazor_version = metadata_lines.next().unwrap();
let tauri_version = metadata_lines.next().unwrap(); let tauri_version = metadata_lines.next().unwrap();
let app_commit_hash = 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 pdfium_version = metadata_lines.next().unwrap();
let vector_store_version = metadata_lines.next().unwrap(); let vector_store_version = metadata_lines.next().unwrap();
let metadata = MetaData { 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_commit_hash: app_commit_hash.to_string(),
app_version: app_version.to_string(), app_version: app_version.to_string(),
build_number: build_number.to_string(), build_number: build_number.to_string(),
+1 -43
View File
@@ -6,10 +6,7 @@ use std::sync::OnceLock;
use log::{info, warn}; use log::{info, warn};
use tokio::process::Command; use tokio::process::Command;
use crate::environment::{DATA_DIRECTORY, is_flatpak}; 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(); static HAS_LOGGED_PANDOC_PATH: OnceLock<()> = OnceLock::new();
const FLATPAK_PANDOC_PLUGIN_BIN_DIRECTORY: &str = "/app/plugins/pandoc/bin"; 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. /// Determines the executable name based on the OS the runtime is built for.
///
/// This uses runtime detection instead of metadata to ensure correct behavior
/// on dev machines where the metadata may contain stale values.
fn pandoc_executable_name() -> String { 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 { match std::env::consts::OS {
"windows" => "pandoc.exe".to_string(), "windows" => "pandoc.exe".to_string(),
_ => "pandoc".to_string(), _ => "pandoc".to_string(),